收集类型的初始容量,例如,字典和列表
.NET中的某些收集类型具有可选的“初始容量”构造函数参数。例如:
Dictionary<string, string> something = new Dictionary<string, string>(20);
List<string> anything = new List<string>(50);
我似乎找不到这些对象在。
如果我知道我只会在词典中存储12个左右的项目,那么将初始能力设置为20之类的东西是否有意义?
我的理由是,假设容量会像弦乐器一样增长,每次击中容量时,每次击中容量都会增加一倍,而每个重新分配都很昂贵,为什么不预设您所知道的东西的大小会持有您的数据,只有一些额外的空间以防万一?如果初始容量是100,我知道我只需要十二次,似乎将其余的内存分配给任何一无所有。
Certain collection types in .NET have an optional "Initial Capacity" constructor parameter. For example:
Dictionary<string, string> something = new Dictionary<string, string>(20);
List<string> anything = new List<string>(50);
I can't seem to find what the default initial capacity is for these objects on MSDN.
If I know I will only be storing 12 or so items in a dictionary, doesn't it make sense to set the initial capacity to something like 20?
My reasoning is, assuming that the capacity grows like it does for a StringBuilder, which doubles each time the capacity is hit, and each reallocation is costly, why not preset the size to something you know will hold your data, with some extra room just in case? If the initial capacity is 100, and I know I will only need a dozen or so, it seems as though the rest of that memory is allocated for nothing.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果未记录默认值,则最佳初始容量可能是实现细节,并且可能会在框架版本之间进行更改。也就是说,您不应编写假定某个默认值的代码。
构造函数具有容量的重载是您比班级更了解的情况。例如,如果您创建50个值的集合并知道该数字将永远不会增加,则可以使用50个容量来初始化该集合,因此如果默认容量较低,则不必调整大小。
也就是说,您可以使用反射器确定默认值。例如,在.NET 4.0(也可能是以前的版本)中,
a List&lt; t&gt;以0的能力初始化。当添加第一项时,将其重新引导至4。随后,每当达到容量时,容量都会加倍。
字典&lt; t&gt;具有0的能力为0。但是它使用完全不同的算法来增加容量:它始终增加了质数的能力。
If the default values are not documented, the reason is likely that the optimal initial capacity is an implementation detail and subject to change between framework versions. That is, you shouldn't write code that assumes a certain default value.
The constructor overloads with a capacity are for cases in which you know better than the class what number of items are to be expected. For example, if you create a collection of 50 values and know that this number will never increase, you can initialize the collection with a capacity of 50, so it won't have to resize if the default capacity is lower.
That said, you can determine the default values using Reflector. For example, in .NET 4.0 (and probably previous versions as well),
a List<T> is initialized with a capacity of 0. When the first item is added, it is reinitialized to a capacity of 4. Subsequently, whenever the capacity is reached, the capacity is doubled.
a Dictionary<T> is intialized with a capacity of 0 as well. But it uses a completely different algorithm to increase the capacity: it increases the capacity always to prime numbers.
如果您知道尺寸,请告诉它;在大多数“小”案例中是一个较小的优化,但可用于更大的收藏。如果我投入“不错的”数据,我会主要担心这一点,因为它可以避免必须分配,复制和收集多个数组。
大多数收藏确实使用了加倍策略。
If you know the size, then tell it; a minor optimisation in most "small" cases, but useful for bigger collections. I would mainly worry about this if I am throwing a "decent" amount of data in, as it can then avoid having to allocate, copy and collect multiple arrays.
Most collections indeed use a doubling strategy.
检查源,
列表的默认容量&lt; t&gt;
和dictionary&lt; tkey,tvalue&gt;
是0。Checking the source, the default capacity for both
List<T>
andDictionary<TKey, TValue>
is 0.(当前)的另一个问题(当前)以及使用其构造函数设置初始大小的问题是,其性能似乎受到阻碍。
例如,这是一些示例代码和基准测试我尝试过。
我在计算机上运行了代码,并得到了类似的结果。
也就是说,当指定初始尺寸时,它在添加对象时无助于增加同意的速度。从技术上讲,我认为应该,因为它不必花时间或资源来调整大小。
是的,它的运行可能不如普通词典那样快,但是我仍然期望与没有初始尺寸集的并发性限制相比,其初始尺寸设置的均匀性能是一致,更快的性能,尤其是当人们提前知道时将添加的项目数量。
因此,故事的寓意是设定初始尺寸并不总是保证提高性能。
Another issue with the ConcurrentDictionary (currently) and using its constructor to set an initial size is that its performance appears to be hindered.
For example, here's some example code and benchmarks I tried.
I ran the code on my machine and got similar results.
That is, when the initial size is specified, it does nothing to increase the ConcurrentDictionary's speed when adding objects. Technically, I think it should because it doesn't have to take time or resources to resize itself.
Yes, it may not run as fast as a normal Dictionary, but I would still expect a ConcurrentDictionary with its initial size set to have consistent, faster performance than a ConcurrentDictionary that doesn't have its initial size set, especially when one knows in advance the number of items that are going to be added to it.
So the moral of the story is setting the initial size doesn't always guarantee a performance improvement.
使用此正则表达式
新列表[&lt;]。 kbd> shift + f 带有正则表达式选项,以搜索所有可能必须添加初始容量的列表;-)
Use this regular expression
new List[<].*[>][(\(\))?[ ]+[{]
in Visual Studio Ctrl+Shift+F with regular expression option on to search all lists that you might have to add an initial capacity to it ;-)