c#Paradox:将列表转换为数组更有效率吗?

zaf*_*ena 2 c# arrays performance

列表基准:大小= 1000,运行= 50000,总时间= 19.5秒

var list = new List<string>(Size);
for (int i = 0; i < Size; i++) list.Add(i.ToString());

var b = new Benchmark();
b.Test("TestListIteration", () =>
{
   c = 0;
   for (int i = 0; i < Runs; i++)
   {
      for (int j = 0; j < Size; j++)
      {
          c += list[j].Length;
      }
   }
});
Run Code Online (Sandbox Code Playgroud)

列表到数组基准:大小= 1000,运行= 50000,总时间= 15.449

var list = new List<string>(Size);
for (int i = 0; i < Size; i++) list.Add(i.ToString());

var b = new Benchmark();
b.Test("TestListIteration", () =>
{
   c = 0;
   for (int i = 0; i < Runs; i++)
   {
      var array = list.ToArray(); //Changed line here !!!
      for (int j = 0; j < Size; j++)
      {
          c += array[j].Length;
      }
   }
});
Run Code Online (Sandbox Code Playgroud)

这不是一个悖论吗?

如何执行两个操作
a)将整个列表转换为数组,以及
b)迭代整个数组.
比单独做b更快(迭代列表).

如果是这种情况,那么这意味着世界上编写的所有代码都是错误的.我们应该预测这个案子.并且列表中的每个"For"循环应该在启动之前自动调用.ToArray.即使数组稍后被丢弃.

编辑:以下是取决于"大小"的结果.

大小= 10,运行= 5000000:列表胜利列表:20.362,ListToArray:37.36

大小= 100,运行= 500000:列表胜利列表:19.64,ListToArray:23.162

Size = 1000,Runs = 50000:ListToArray Wins List:19.5,ListToArray:15.449

Size = 10000,Runs = 5000:ListToArray Wins List:20.094,ListToArray:14.453

大小= 10000000,运行= 5:计算机死亡

Eri*_*ert 14

这不是一个悖论吗?

没有.

如何执行两个操作a)将整个列表转换为数组,以及b)迭代整个数组.比单独做b(迭代列表)更快?

将列表转换为数组的速度非常快.

迭代元素的元素比迭代元素的元素得多.

为什么这些事情是真的?

因为(1)列表是幕后的秘密数组,(2)数组到数组的复制是大量优化的 - 它是通过直接转到硬件而不是通过迭代每个元素并一次复制一个来完成的 - 所以列表到数组的复制也经过了大量优化,并且(3)列表索引只是数组索引加上更多的工作,因此列表索引必须稍微慢一些.

正如你所发现的那样,当你平衡一个非常快的东西与许多稍微慢一点的东西时,就会有一个人会胜过另一个.

如果是这种情况,那么这意味着世界上编写的所有代码都是错误的.

不,不是的.

我们应该预测这个案子.

不,我们不应该担心它.不相信我?只要找到我今天在市场上的产品,其成功或失败完全取决于选择快速几毫秒的列表迭代技术.

并且列表中的每个"For"循环应该在启动之前自动调用.ToArray.

绝对不.即使我们知道它更快,我们也不知道,但有许多性能需要担心.为了节省几毫秒,将正在使用的内存量加倍可以直接抵消最小化内存使用的性能目标! 不是每个人都关心原始速度.

在您的情况下,50000次运行的差异为4000毫秒,因此每次运行时节省的时间不到十分之一毫秒.如果您关心十分之一毫秒,那么无论如何都要对您的代码进行更改.