为什么没有Dictionary.TrimExcess()?

时间:2009-10-26 14:25:21

标签: .net collections dictionary

在.NET中,Dictionary<TKey, TValue>有一个构造函数,它带有一个参数int capacity。这与许多其他集合相同,例如List<T>Queue<T>Stack<T>;此外,根据the MSDN documentation

  

Dictionary的容量是在需要调整大小之前可以添加到Dictionary的元素数。当元素添加到Dictionary时,通过重新分配内部数组,容量会根据需要自动增加。

这对我来说与List<T>等其他集合几乎相同。由于这些集合在必要时具有自动调整大小的行为,因此可能具有比所需更大的容量,其中大多数都具有一个TrimExcess方法。如果您一次向集合中添加未知数量的项目,那么这将非常方便,之后您将不会添加任何其他项目。

为什么Dictionary<TKey, TValue>没有相同的TrimExcess方法?

(免责声明:我非常熟悉“默认情况下不存在的功能”响应;我想我大多只是想知道TrimExcess Dictionary的{​​{1}}是否存在特殊原因没有意义,或者为什么它比List这样的简单集合更难实现。)

5 个答案:

答案 0 :(得分:6)

我猜在这种情况下,capacity参数有助于定义散列函数以及桶的数量;调整稀疏数据集的大小/修整将需要重新计算剩余的所有存储项的哈希值。

答案 1 :(得分:5)

这是部分猜测:字典被“排序”为哈希表。保留的容量不仅仅是字典顶部的一堆空闲内存地址。相反,它包含整个字典中的空房间。这样做是为了使添加/移动/移除等非常有效。如果您对Dictionary有TrimExcess方法,则整个Dictionary必须将所有内容复制到新位置,而且元素之间没有任何间隙。

实际上:差距应保持不变,否则哈希表的好处将变为无效,修剪(TrimExcess),如果实施,应该只修剪内部ValueCollection

更新:扩展并更改了我选择不当的单词
更新: the BCL team says TrimExcess for Dictionaries "could be useful" 更新:功能请求已解决,因为无法修复:“不幸的是,我们无法在下一版本的.NET中找到它,所以我'我解决这个问题并不会解决。“

答案 2 :(得分:4)

每个MSDN Dictionary实现为哈希表。如果你削减了多余的部分,你就必须提出一种算法,该算法仍然提供接近O(1)的查找时间,实际上是一个随机排序的列表。

答案 3 :(得分:1)

实际上我是那个要求微软实施TrimExcess的人。 我已经提交了多篇涉及字典的文章,在所有情况下我都实现了TrimExcess。实际上,当增加或减小桶的大小时,可以调用当桶太小时使用的Resize。

今天我刚发表了另一篇文章,它是一个字典的C ++实现,它支持TrimExcess: http://www.codeproject.com/Articles/761040/A-NET-like-Dictionary-in-Cplusplus

本文中可以找到另一种实现(.NET): http://www.codeproject.com/Articles/548406/Dictionary-plus-Locking-versus-ConcurrentDictionar

答案 4 :(得分:0)

到2019年,.Net Standard 2.1+和.Net Core 2.1+实施Dictionary<TKey, TValue>.TrimExcess()

请参阅:https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.trimexcess?view=netstandard-2.1

.Net Framework在任何版本中均未实现。