C# 列表的大小越大,添加新值所需的时间就越多,这是真的吗?

C# 列表的大小越大,添加新值所需的时间就越多,这是真的吗?,c#,list,C#,List,我正在制作一个程序,它可以从internet实时连续接收数据字符串类型。为了提高性能,它将新数据存储在listmemory中,并且每天只将其写入文件一次 我想知道列表的大小是否越大,添加新值所需的时间就越多。例如,在性能方面,将新数据添加到大小为10的列表和将新数据添加到大于3000000的列表之间有什么区别吗?我想知道,如果我从一开始就设置列表的默认大小,比如新列表3000000,性能是否会有任何差异 如果我能得到一些关于如何更好地完成这项工作的建议,我将不胜感激。这是向列表中添加项目的实际源

我正在制作一个程序,它可以从internet实时连续接收数据字符串类型。为了提高性能,它将新数据存储在listmemory中,并且每天只将其写入文件一次

我想知道列表的大小是否越大,添加新值所需的时间就越多。例如,在性能方面,将新数据添加到大小为10的列表和将新数据添加到大于3000000的列表之间有什么区别吗?我想知道,如果我从一开始就设置列表的默认大小,比如新列表3000000,性能是否会有任何差异


如果我能得到一些关于如何更好地完成这项工作的建议,我将不胜感激。

这是向列表中添加项目的实际源代码,您可以在这里找到

如果我能得到一些关于更好的方法的建议,我将不胜感激 工作


如果这真的是任务关键型的东西,并且您希望节省垃圾收集器和大型对象堆上的分配和内存压力,那么只需创建一个容量集足够大的列表或一个数组,然后重用它。然而,我真诚地认为,您可能还需要首先担心其他事情。

这是向列表中添加项目的实际源代码,您可以在这里找到

如果我能得到一些关于更好的方法的建议,我将不胜感激 工作


如果这真的是任务关键型的东西,并且您希望节省垃圾收集器和大型对象堆上的分配和内存压力,那么只需创建一个容量集足够大的列表或一个数组,然后重用它。然而,在我诚实的意见中,你可能还需要首先担心另外一件事。

正如迈克尔·兰德尔(Michael Randall)在他精彩的投票回答中指出的那样,实际问题的答案是肯定的。然而,即使我们知道列表变大会使添加项目的速度变慢,我们仍然有一个问题。您可以创建一个列表列表


为了简单起见,我将外部列表称为列表列表列表,内部列表称为外部列表中的列表。首先创建第一个内部列表,让项目进入,直到它变得相当大,比如说10000个元素。然后,创建下一个内部列表,并将新项目放在那里,直到达到限制。不停地,不停地。这意味着在一天结束时,您可能会有300个列表,每个列表都有10000个元素。这会使你的工作略微复杂化,但会消除你在添加项目时的性能下降。

正如迈克尔·兰德尔(Michael Randall)在他精彩的投票回答中指出的那样,实际问题的答案是肯定的。然而,即使我们知道列表变大会使添加项目的速度变慢,我们仍然有一个问题。您可以创建一个列表列表


为了简单起见,我将外部列表称为列表列表列表,内部列表称为外部列表中的列表。首先创建第一个内部列表,让项目进入,直到它变得相当大,比如说10000个元素。然后,创建下一个内部列表,并将新项目放在那里,直到达到限制。不停地,不停地。这意味着在一天结束时,您可能会有300个列表,每个列表都有10000个元素。这将略微使您的工作复杂化,但在您添加项目时会避免性能下降。

我可以想出一种非常简单的方法让您自己进行测试。我建议您查看列表的源代码以及动态调整数组大小的原则。简言之:分配一个空数组,比如说,8个元素,如果向其中添加项目使其变满,则分配一个包含16个元素的新数组,并复制现有的8个元素,然后重复32、64、128大小的数组。如果阵列不需要重新分配,则添加新项目是O1,否则它将打开。无法想象为什么它会变慢-除了内部阵列的不断调整大小之外,内部阵列的时间复杂度应该是线性的。除此之外,我同意你的看法,只要试一下,自己测量一下。把列表的容量设置得足够大,那么它就不需要调整大小了。然而,列表大小确实是一个值得注意的开销或性能问题,在任何通常意义上。我想知道,如果我从一开始就设置列表的默认大小,性能是否会有任何差异。如果您认为一天的数据可以容纳在3000000以内,这将有所帮助,因为它永远不需要在给定的一天中创建新数组。即使它超过了这个大小,您也将避免使用默认容量创建和复制许多新阵列,并避免对旧阵列进行GCing,其中许多是在LOH中。缺点是,您在RAM中为3000000个元素保留了空间,即使是在一天开始的时候
你可能只需要20个。我可以想出一个非常简单的方法让你自己测试这个。我建议您查看列表的源代码以及动态调整数组大小的原则。简言之:分配一个空数组,比如说,8个元素,如果向其中添加项目使其变满,则分配一个包含16个元素的新数组,并复制现有的8个元素,然后重复32、64、128大小的数组。如果阵列不需要重新分配,则添加新项目是O1,否则它将打开。无法想象为什么它会变慢-除了内部阵列的不断调整大小之外,内部阵列的时间复杂度应该是线性的。除此之外,我同意你的看法,只要试一下,自己测量一下。把列表的容量设置得足够大,那么它就不需要调整大小了。然而,列表大小确实是一个值得注意的开销或性能问题,在任何通常意义上。我想知道,如果我从一开始就设置列表的默认大小,性能是否会有任何差异。如果您认为一天的数据可以容纳在3000000以内,这将有所帮助,因为它永远不需要在给定的一天中创建新数组。即使它超过了这个大小,您也将避免使用默认容量创建和复制许多新阵列,并避免对旧阵列进行GCing,其中许多是在LOH中。缺点是,您在RAM中为3000000个元素保留了空间,即使在一天开始时您可能只需要20个。上次我尝试创建一个>10k个元素的列表时,出现了内存不足异常。在12GiB ram系统中;有一张短裤清单。顺便说一句,我刚看了你的个人资料,你的故事听起来和我的很像xD@Marc.2377很高兴见到志同道合的人。该列表需要进行压力测试。如果系统不能承受如此多的元素,那么我们可以将其减少到一个较小的数字,如5000。上次我试图创建一个>10k元素的列表时,我遇到了内存不足异常。在12GiB ram系统中;有一张短裤清单。顺便说一句,我刚看了你的个人资料,你的故事听起来和我的很像xD@Marc.2377很高兴见到志同道合的人。该列表需要进行压力测试。如果系统不能承受如此多的元素,那么我们可以将其减少到一个较小的数字,如5000。
public void Add(T item)
{
   if (_size == _items.Length) EnsureCapacity(_size + 1);
   _items[_size++] = item;
   _version++;
}

private void EnsureCapacity(int min)
{
   if (_items.Length < min)
   {
      int newCapacity = _items.Length == 0 ? _defaultCapacity : _items.Length * 2;
      // Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow.
      // Note that this check works even when _items.Length overflowed thanks to the (uint) cast
      if ((uint)newCapacity > Array.MaxArrayLength) newCapacity = Array.MaxArrayLength;
      if (newCapacity < min) newCapacity = min;
      Capacity = newCapacity;
   }
}

public int Capacity
{
   ...
   set
   {
      ...
      if (value != _items.Length)
      {
         if (value > 0)
         {
            T[] newItems = new T[value];
            if (_size > 0)
            {
               Array.Copy(_items, 0, newItems, 0, _size);
            }
            _items = newItems;
         }
         else
         {
            _items = _emptyArray;
         }
      }
   }
}
var r = new Random();
var bytes = new byte[100000000];
var bytes2 = new byte[100000000];
r.NextBytes(bytes);

var sw = Stopwatch.StartNew();
Array.Copy(bytes,bytes2,bytes.Length);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);