预分配列表c#

时间:2013-10-07 16:07:36

标签: c# data-structures

我在c#中工作,我正在创建一个列表(newList),我可以从另一个列表的长度(otherList)中获取。在c#中列表实现的方式是预先分配列表的长度对于使用otherList.Count的性能更好或者只是使用newList.Add(obj)而不用担心长度?

4 个答案:

答案 0 :(得分:7)

实现List<T>的以下构造函数是为了提高像您这样的场景中的性能:

http://msdn.microsoft.com/en-us/library/dw8e0z9z.aspx

public List(int capacity)

只需传递构造函数中的容量。

newList = new List<string>(otherList.Count);

答案 1 :(得分:4)

如果您知道新列表的确切长度,那么使用该容量创建它确实可以 - 稍微好一些。

原因是List<T>的实现在内部使用数组。如果这个太小,则会创建一个新数组,并将旧数组中的项目复制到新项目中。

答案 2 :(得分:4)

摘自MSDN

上的备注部分
  

List<T>的容量是List<T>的元素数量   能把持住。当元素添加到List<T>时,通过重新分配内部数组,容量会根据需要自动增加。

     

如果可以估算集合的大小,则指定初始容量消除了在向List<T>添加元素时执行大量调整大小操作的需要。

     

可以通过调用TrimExcess方法或通过调用容量来减少容量   显式设置Capacity属性。减少容量   重新分配内存并复制List<T>中的所有元素。

因此,如果您估计要填充的列表的大小,这表明会有性能提升。当然,另一方面是将列表大小分配得太大,因此不必要地占用内存。

老实说,除非我真的需要,否则我不会担心这种微观优化。

答案 3 :(得分:0)

因此,我对预分配方案进行了基准测试,只想分享一些数字。该代码只是对此进行计时:

var repetitions = 100000000
var list = new List<object>();
for (var i = 0; i < repetitions; i++)
    list.Add(new object());

比较是通过在列表中分配准确的重复次数,重复次数的两倍而不进行预分配。现在是时候了:

  • 未预先分配的列表:6561、6394、6556、6283、6466
  • 列表已预先分配:5951、6037、5885、6044、5996
  • 列表中已预分配的重复项:6710、6665、6729、6760、6624

那么预分配值得吗?是的,如果知道列表中对象的数量,或者知道此数量的底线(列表中至少有多少个项目)。

否则,您可能会冒实际上浪费更多时间和内存的风险,因为预分配将使用时间和内存来为所需的分配腾出空间。

请注意,就内存而言,精确的预分配是最有效的内存使用方法,因为不进行预分配会使您的列表超出最紧迫的所需容量。