【问题标题】:Why using powers of 2 as the hash size makes a hash table considerably worse than using primes?为什么使用 2 的幂作为哈希​​大小会使哈希表比使用素数更糟糕?
【发布时间】:2014-10-17 21:09:28
【问题描述】:

我正在实现一个哈希表,它应该存储成对的 32 位值。考虑到我的元素是固定大小的,我使用了一个非常简单的散列函数:

hash(a,b) = asUint64(a) + (asUint64(b) << 32)

这样,我得到哈希表(即其对应的桶)中元素的索引:

index(a,b) = hash(a,b) % hash_size

其中 hash_size 是我表上的条目/存储桶数。不过,我已经意识到,如果我用 bitwise mod of 2 替换“模数”运算符,通过将 hash_size 固定为 2 的幂,我可以稍微加快这个实现。除了,当我这样做时,我的大多数配对最终都在第一个桶上!为什么会发生这种情况?

【问题讨论】:

  • 如果你使用 2 的幂进行修改,你将破坏b 中存在的大量数据,并且可能会破坏a
  • 我想这听起来很合理,但为什么呢?
  • 奇怪的是,你说你的大多数配对最终都在第一个桶上。我预计与此方案会发生更多冲突,但我怀疑您的情况更多是由于您的数据分布所致。
  • 使用 MurmurHash3 avalanche 函数重新散列哈希并继续使用 2 大小的幂。
  • 你也可以找到this answer有用

标签: math hash language-agnostic hashtable bit-manipulation


【解决方案1】:

我的猜测是您的数据在a 中分布不均。考虑将ab 串联为您的哈希码:

b31b30...b1b0a31a30...a1a0, where ai, bi is the ith bit of a,b

假设您有一个包含一百万个条目的表,那么您的哈希索引是

a9a8...a1a0 (as an integer)

更糟糕的是,假设 a 的范围仅从 1 到 100。那么您对 ​​a 的高阶位的依赖就更少了。

如您所见,如果您的哈希表没有至少 40 亿个条目,则您的哈希码完全不依赖于 b,hash(x, a) 将与所有 x 发生冲突。

【讨论】:

  • 这很有启发性,谢谢。这不在问题的范围内,所以请随意不要回答,但是在这种情况下您会推荐什么散列函数?
猜你喜欢
  • 1970-01-01
  • 2014-12-04
  • 2011-08-21
  • 2014-06-01
  • 2021-01-07
  • 2011-04-25
  • 2014-05-17
  • 2011-04-28
相关资源
最近更新 更多