为什么.Net词典会调整为素数?

maa*_*ank 13 .net algorithm primes computer-science data-structures

根据这个问题,.Net字典将其分配的空间大小调整为至少是当前大小两倍的素数.为什么使用素数而不仅仅是当前大小的两倍是很重要的?(我试图用我的google-fu功能找到答案,但无济于事)

Cod*_*aos 16

放置元素的桶由下式确定(hash & 0x7FFFFFF) % capacity.这需要均匀分布.由此得出,如果多个条目是某个基数(hash1 = x1 * base,hash2 = x2 * base...)的倍数,其中base并且capacity不是互质(最大公约数> 1),则过度使用某些时隙,并且从不使用某些时隙.由于素数与除自身之外的任何数字都是互质的,因此它们具有相对较好的实现良好分布的机会.

一个特别好的属性是,capacity > 30每个位对哈希码的贡献是不同的.因此,如果散列的变化仅集中在几位中,那么它仍将导致良好的分布.这解释了为什么两个幂的容量都很差:它们掩盖了高位.只有高位不同的一组数字并非不太可能.

我个人认为他们选择的功能很糟糕.它包含一个昂贵的模运算,如果条目是素数容量的倍数,它的性能就会崩溃.但对大多数应用来说似乎已经足够了.


Dar*_*rov 11

它是与选择良好的散列函数相关的算法实现细节,并且提供均匀分布.非均匀分布增加了碰撞次数和解决它们的成本.

  • 选择素数不会**提供均匀分布,不需要过度简化.使用`hashsize = prime_number`,你获得碰撞的几率与使用`hashsize = 2 ^ k`或其他任何东西完全相同.只是一些散列大小使得碰撞看起来"不可预测","随机"或"均匀分布".另一方面,使用`hashsize = 2 ^ k`意味着任何基于xor的散列函数都会很糟糕. (6认同)

小智 5

由于素数的数学,它们不能被分解成不同的较小数.当您从存储的项目中划分哈希值时,您将获得相同的分布.如果您没有素数,根据对象,分布可能不均匀.