简体   繁体   English

确定收集对象的初始容量的最佳方法是什么?

[英]What is the best way to determine the initial capacity for collection objects?

When using objects that have a capacity, what are some guidelines that you can use to ensure the best effeciency when using to collections?使用具有容量的对象时,您可以使用哪些准则来确保在使用 collections 时获得最佳效率? It also seems like .NET framework has set some of these capacities low. .NET 框架似乎也将其中一些容量设置得很低。 For example, I think StringBuilder has an intial capacity of 16. Does this mean that after 16 strings are inserted into the StringBuilder, the StringBuilder object is reallocated and doubled in size?例如,我认为StringBuilder的初始容量为16。这是否意味着在StringBuilder中插入16个字符串后,StringBuilder object被重新分配并且大小增加了一倍?

If you know how large a collection or StringBuilder will be up front, it is good practice to pass that as the capacity to the constructor.如果您预先知道集合或 StringBuilder 的大小,最好将其作为容量传递给构造函数。 That way, only one allocation will take place.这样,只会发生一次分配。 If you don't know the precise number, even an approximation can be helpful.如果您不知道确切的数字,即使是近似值也会有所帮助。

With StringBuilder , it isn't the number of strings , but the number of characters .使用StringBuilder ,它不是字符串的数量,而是字符的数量。 In general;一般来说; if you can predict the length, go ahead and tell it - but since it uses doubling, there isn't a huge overhead in reallocating occasionally if you need to juts use Add etc.如果您可以预测长度,请提前 go 并告诉它 - 但由于它使用加倍,如果您需要使用Add等,偶尔重新分配不会有很大的开销。

In most cases, the difference will be trivial and a micro-optimisation.在大多数情况下,差异将是微不足道的和微优化。 The biggest problem with not telling it the size is that unless the collection has a "trim" method, you might have nearly double the size you really needed (if you are very unlucky).不告诉它大小的最大问题是,除非集合具有“修剪”方法,否则您的大小可能几乎是您真正需要的大小的两倍(如果您很不幸的话)。

There are only two circumstances where I ever explicitly set the capacity of a collection只有两种情况我会明确设置集合的容量

  1. I know the exact number of items that will appear in the collection and I'm using an Array or List<T>.我知道将出现在集合中的项目的确切数量,并且我使用的是 Array 或 List<T>。
  2. I am PInvoking into a function which writes to a char[] and i'm using a StringBuilder to interop with parameter.我正在调用 function 写入 char[] 并且我正在使用 StringBuilder 与参数进行互操作。 In this case you must set a capacity for the CLR to marshal to native code.在这种情况下,您必须为 CLR 设置容量以编组为本机代码。

Interestingly, for #1 it is almost always done when I am copying data returned from a COM interface into a BCL collection class.有趣的是,对于#1,它几乎总是在我将从 COM 接口返回的数据复制到 BCL 集合 class 时完成。 So I guess you could say I only ever do this in interop scenarios:).所以我想你可以说我只在互操作场景中这样做过:)。

Speaking of StringBuilder , I'd dare to use the worst-case size.说到StringBuilder ,我敢于使用最坏情况的大小。 StringBuilder requires contigous memory block, which is hard to allocate on a highly fragmented heap. StringBuilder需要连续的 memory 块,这很难在高度碎片化的堆上分配。

I'd go with an estimation for other collections, though.不过,我会用 go 估计其他 collections。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM