更复杂的散列函数会导致更快地构建表吗



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

所以这里有两件事需要考虑——hashing time complexitycollision resolution time complexity

通常,散列函数的运行时间是恒定的,或者它线性地取决于输入键的大小。也就是说,constant时间并不意味着它不取决于密钥的大小,而只是这样一个事实,即如果对整数进行运算,那么今天的典型计算机速度相当快,可以将它们视为常数。

因此,如果您有一个更简单的散列函数,如h(k) = k % m,其中%是模运算符,它的执行速度将比其他函数更快,比如h(k) = ( (k << 16) ^ k ) % m,其中^是逐位异或运算符。

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

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

此外,如果您只是执行插入操作,那么使用Chaining来解决冲突是有意义的,因为这可以确保O(1)即使在冲突期间也能插入,而不是探测方法。请注意,这仅适用于哈希表中的插入操作。因此,如果你的问题只是关于构建哈希表,那么就使用Chaining中更简单的哈希函数。冲突仍然存在,但插入将是O(1)

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

最新更新