C# - List.ToArray() 为单个元素花费几毫秒

Posted

技术标签:

【中文标题】C# - List.ToArray() 为单个元素花费几毫秒【英文标题】:C# - List.ToArray() taking several ms for a single element 【发布时间】:2018-09-03 15:17:21 【问题描述】:

我有以下代码,由于某种原因,ToArray() 方法对单个元素需要 7 毫秒。该应用程序有几个工作线程发生这种情况,我还使用 JetBrains dotTrace 分析了该应用程序,这表明该线程正在等待另一个线程(而不仅仅是等待 CPU),这显然是不可能的,因为List 是一个局部变量,我不使用锁。

List<TransactionType> transactionTypes = 
   new List<TransactionType>(_TransactionTypes.LengthNull() + 
   drawingAction._TransactionTypes.LengthNull())
...
Stopwatch sw = Stopwatch.StartNew();
_TransactionTypes = transactionTypes.ToArray();
sw.Stop();
if (sw.ElapsedMilliseconds > 3)

  int deb = 0;

这种现象几乎发生在使用 .Net 框架的方法(例如 String.Format)的每个地方。我有这个问题有一段时间了,由于某种原因,在主线程中使用 SpinWait 会使情况变得更糟。

我和我的同事都对此没有任何解释,Google 也没有提供帮助,因此我非常感谢您的帮助。

发现问题: 或者至少是其中的一部分。它似乎是由 GC 压力引起的,我已经知道如何在应用程序中减少它。我仍然不知道为什么 SpinWait 有时会导致线程阻塞,但我只是不使用它。

这个问题被标记为重复,Stack Overflow 告诉我编辑它以解释原因,但老实说,如果你甚至费心阅读标题,这很明显。

【问题讨论】:

编写ToArray 的基本实现并将您的诊断Stopwatch 检查放入其中。如果您发现缓冲区数组分配占用了大部分执行时间,则表明 GC 压力或可能是整体系统负载问题。您可以使用the actual ToList method source 作为起点,如果需要,可以通过将Array.Copy 替换为for 循环来进一步增加粒度。 我重新打开了这个问题,因为它显然不是 ***.com/questions/1147497/… 的重复项(它只是问,“我听说 ToArray 很慢;是这样吗?”) 【参考方案1】:

我刚刚查看了 .NET 源代码。所以显然它只是将列表数组的当前内容复制到一个新数组中。

T[] array = new T[_size];
Array.Copy(_items, 0, array, 0, _size);   //_items is the lists inner array     
return array;

只是复制而已。

【讨论】:

是的,我知道,这就是我如此困惑的原因。 我已经在 *** 上发现了同样的问题。 link注意有人说将第一个元素添加到列表中容量增加到16的答案

以上是关于C# - List.ToArray() 为单个元素花费几毫秒的主要内容,如果未能解决你的问题,请参考以下文章

转ArrayList的toArray,也就是list.toArray[new String[list.size()]];,即List转为数组

toArray()方法使用说明

Java 向数组中添加一个元素

添加数组类

JavaList转化为数组

find()、findOrFail()、first()、firstOrFail()、get()、list()、toArray() 有啥区别