Math 为什么使用2的幂作为散列大小会使散列表比使用素数更糟糕?

Math 为什么使用2的幂作为散列大小会使散列表比使用素数更糟糕?,math,hash,language-agnostic,hashtable,bit-manipulation,Math,Hash,Language Agnostic,Hashtable,Bit Manipulation,我正在实现一个哈希表,它应该存储32位值对。考虑到我的元素是固定大小的,我使用了一个非常简单的哈希函数: hash(a,b) = asUint64(a) + (asUint64(b) << 32) 其中hash_size是我的表中的条目数/存储桶数。不过,我已经意识到,如果我将“模数”操作符替换为a,通过将hash_大小固定为2的幂,我可以稍微加快这个实现除了,当我这样做的时候,我的大多数搭档都会在第一个桶上结束为什么会发生这种情况 我猜您的数据在a中分布不均匀。考虑 > >

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

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

其中hash_size是我的表中的条目数/存储桶数。不过,我已经意识到,如果我将“模数”操作符替换为a,通过将hash_大小固定为2的幂,我可以稍微加快这个实现除了,当我这样做的时候,我的大多数搭档都会在第一个桶上结束为什么会发生这种情况

我猜您的数据在
a
中分布不均匀。考虑<代码> > <代码> > <代码> b>代码>作为哈希代码:

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

产生冲突,如果您使用2的幂进行修改,您将破坏
b
中存在的大量数据,可能还会破坏
a
。我想这听起来很合理,但是为什么呢?你说你的大多数情侣最后都会在第一桶里,这很奇怪。我希望这个方案会有更多的冲突,但我怀疑你的情况更多的是由于你的数据的分布。用雪崩函数重新刷新你的散列,继续使用2大小的幂函数。你也会发现有用的,这很有启发性,谢谢。这不在问题的范围之内,所以请不要回答它,但是在这种情况下,您会推荐什么哈希函数?
a9a8...a1a0 (as an integer)