根据this question,.Net字典将其分配的空间大小调整为至少是当前大小两倍的素数。为什么使用素数而不仅仅是当前大小的两倍是很重要的? (我试图用我的google-fu功能找到答案,但无济于事)
答案 0 :(得分:15)
放置元素的存储区由(hash & 0x7FFFFFF) % capacity
确定。这需要均匀分布。由此得出,如果多个条目是某个基数(hash1 = x1 * base
,hash2 = x2 * base
,......)的倍数,其中base
和capacity
不是互质的(最大公约数> 1)一些插槽过度使用,有些插槽从未使用过。由于素数与除了他们自己之外的任何数字都是互质的,因此他们有相对较好的机会获得良好的分布。
这是一个特别好的属性,对于capacity > 30
,每个位对哈希码的贡献是不同的。因此,如果散列的变化仅集中在几位中,那么它仍将导致良好的分布。这解释了为什么两个幂的容量都很差:它们掩盖了高位。只有高位不同的一组数字并非不太可能。
我个人认为他们选择的功能很差。它包含一个昂贵的模运算,如果条目是素数容量的倍数,它的性能就会崩溃。但对大多数应用来说似乎已经足够了。
答案 1 :(得分:11)
这是与choosing a good hashing function相关的算法实现细节,它提供了均匀分布。非均匀分布会增加碰撞次数和解决它们的成本。
答案 2 :(得分:5)
由于素数的数学,它们不能被分解成不同的较小数。当您从存储的项目中划分哈希值时,您将获得相同的分布。如果你没有素数,取决于对象,分布可能不均匀。