这篇文章会介绍,.net中Dictionary每次扩容的时候,为什么要大于等于原有空间的2倍的最小质数。

回答问题前,先看代码

1:c#中Dictionary的扩容代码,主要看三段:
第一段代码:新增元素前,如果发生扩容,就会调用ExpandPrime()方法,这个方法主要实现两个功能,第一:空间扩大二倍,第二:根据最新的空间(newSize),去调用GetPrime(),返回大于等于newSize的最小质数
Dictionary扩容规律:是大于等于原有空间的2倍的最小质数
第二段代码:返回大于等于newSize的最小质数
Dictionary扩容规律:是大于等于原有空间的2倍的最小质数
第三段代码:这是默认的一组质数(空间换时间),如果大于预置的质数,则会根据质数的算法生成新的质数。
Dictionary扩容规律:是大于等于原有空间的2倍的最小质数

原因:质数使数据分布更均匀

1:Dictionary数据结构图:
Dictionary扩容规律:是大于等于原有空间的2倍的最小质数
2:新增数据的原理(算法):
第一步:数据分配采用Hash算法,先对key进行hash取值,等到的值为hashKey.
第二步:用hashKey除以buckets数目,取余。
例如:key=4,buckets=7
那么:4.GetHashCode()%7=4。这样数据就会被添加到buckets中下标为4的bucket里面

3:为什么质数会使数据分配的均匀:
根据新增算法看下面的demo:
3.1:第一个demo:
key为偶数:2,4,6,8,10,12,14。buckets数量为8。等到的结果是:2,4,6,0,2,4,6。因此buckets下标为 0,2,4,6的buckets会插入数据。
3.2:第二个demo:
key为偶数:2,4,6,8,10,12,14。buckets数量为7。等到的结果是:2,4,6,1,3,5,0。因此buckets下标为 0,1,2,3,4,5,6的buckets会插入数据。
通过这两个demo ,我们得出了一个记录:key为偶数时,质数个buckets会使数据分配的更均匀。

3.3:第三个demo:
key为奇数:3,5,7,9,11,13,15。buckets数量为8。等到的结果是:3,5,7,1,3,5,7。因此buckets下标为 1,3,5,7的buckets会插入数据。
3.4:第四个demo:
key为奇数:3,5,7,9,11,13,15。buckets数量为7。等到的结果是:3,5,0,2,4,6,1。因此buckets下标为 0,1,2,3,4,5,6的buckets会插入数据。
通过这第三个和第四个demo ,我们得出了一个结论:key为奇数时,质数个buckets会使数据分配的更均匀。

结论:质数使数据分配的更均匀。

另外:通过数据研究还可以得出数学规律

1:偶数除以偶数,得到的余数一定是个偶数。
2:偶数除以质数,小于质数得到的余数是偶数,大于质数得到的是奇数。
3:奇数除以偶数,得到的余数一定是个奇数。
4:奇数除以质数,小于质数得到的余数是奇数,大于质数得到的是偶数。

很显然除以质数得到的结果更多,这就恰好说明为什么质数使数据分配的更均匀。

相关文章: