【问题标题】:Would a more complex hash function result in a faster built table?更复杂的散列函数会导致更快的构建表吗?
【发布时间】:2020-05-01 07:38:45
【问题描述】:

一个更简单的哈希函数会比一个更复杂的函数更快地构建一个哈希表吗?显然,更复杂的函数会构建一个冲突更少的更好的表,但这是否也会转化为更快的构建表,因为它可能不需要像更简单的函数那样处理尽可能多的冲突?

【问题讨论】:

  • 是的,理论上这是一种权衡,假设更简单的哈希函数会导致更多的冲突。在实践中,这种权衡通常有利于更好的哈希函数,因为冲突会导致更多的内存访问并且内存访问很慢。

标签: algorithm hashtable


【解决方案1】:

因此,您需要考虑两件事 - hashing time complexitycollision resolution time complexity

通常哈希函数的运行时间是恒定的,或者它线性地取决于输入键的大小。话虽如此,constant 时间并不意味着它不依赖于密钥的大小,而只是这样一个事实,即如果对整数进行操作,今天的典型计算机非常快,可以将它们视为常数。

所以,如果你有一个更简单的散列函数,比如h(k) = k % m,其中% 是模运算符,那么它的执行速度会比其他函数更快,比如h(k) = ( (k << 16) ^ k ) % m,其中^ 是按位异或运算符.

准确地说,第二个哈希函数比第一个多两个整数运算,尽管它仍然是一个常数。如果您在 C++ 等快速语言上运行基准测试并通过执行多个 100 million 插入来构建哈希表,则差异将在几个 milliseconds 的顺序上。确切的差异会因硬件环境而异。但是,差异肯定不会太大。

此外,如果你要问一个有经验的程序员,他会在这两者中选择哪一个,我很确定它会是第二个,因为它不太容易发生冲突.请注意,最后 16 位的任何变化也会改变高位。在大多数情况下,性能冲突造成的负担远远超过计算哈希值造成的负担。

另外,如果您只是执行插入操作,那么使用链式解决冲突是有意义的,因为与探测方法相反,即使在冲突期间也能确保 O(1) 插入。请注意,这仅适用于哈希表中的插入操作。 因此,如果您的问题仅涉及构建哈希表,那么请使用带有链的更简单的哈希函数。碰撞仍然存在,但插入将是 O(1)

有关哈希表以及如何避免高运行时间复杂度的冲突的更多详细信息,请参阅here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    • 2017-02-08
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    相关资源
    最近更新 更多