2010-10-23 44 views
3

我正在调查Dictionary<TKey, TValue>背后的代码。有趣的是在private Insert方法中,有一个bucket似乎在预先大小的阵列中保留空插槽。在Insert方法内部,代码检查桶中是否有剩余元素,并在必要时调整大小。添加的元素数量是质数的一个因子。此外,字典条目属性存储在带有散列码,键和值的结构中。是Dictionary <TKey,TValue>在后备存储中添加空元素吗?

我的问题:目的是什么?这样做是为了防止在足够的内存不可用时尝试将项目添加到字典对象?

注:我不想在这里粘贴任何代码,因为它需要反汇编才能读取。

+2

阅读关于哈希表的实现。 – leppie 2010-10-24 00:02:46

+0

@leppie,我会很高兴 - 得到几个链接? :) – IAbstract 2010-10-24 00:16:11

回答

1

Dictionary<TKey,TValue>对象未使用此方法添加新的空值。它正在做的是预先分配一个后备存储器,用于稍后要求添加的数据。最终目标是平均插入情况不需要分配完成。相反,它会在现有的存储区阵列中找到一个插槽来放置它自己。

您提到的其他一些项目(如素数和散列码)的原因是大多数散列表样式实现的常见属性。相反,在这里他们去各的我要去你指向维基百科文章的主题

+0

根据wiki:*对于单独链接,最糟糕的情况是所有条目都被插入同一个存储桶,在这种情况下,散列表无效,成本就是搜索存储桶数据结构。如果后者是线性列表,则查找过程可能必须扫描其所有条目;所以最坏的成本与表中的条目数量成正比。*我错了吗,还是MS使用这种方法? – IAbstract 2010-10-24 00:58:28

1

每次收集需要调整大小时,它会在堆上造成一些颠簸,需要一些时间。这些“空插槽”被初始化以防止这种情况发生。

有大多数集合的构造函数可让您指定初始大小,初始“潜在”大小和增长因子。就这一点而言,指定确切的大小如果你知道这是最好的做法。

+0

啊......这是有道理的 - 显然,调整大小是进步*和*素数的因素(素数* 2) - 我想这是另一个有趣的方面,并想知道为什么它是用来调整大小的素数。 .. – IAbstract 2010-10-24 00:15:04

+0

是的;我认为在统计方面,他们如何使用素数来增加规模,以及“典型”使用中可能预计的规模增加等等。 heh – 2010-10-24 00:26:01