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

时间:2017-06-06 16:26:40

标签: 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;
      }
   }
});

列表到数组基准:大小= 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;
      }
   }
});

这不是一个悖论吗?

如何执行两项行动
  a)将整个列表转换为数组和
  b)迭代整个数组 比单独做b更快(迭代列表)。

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

编辑:以下是结果取决于&#34;尺寸&#34;。

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

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

大小= 1000,运行= 50000:ListToArray胜出 清单:19.5,ListToArray:15.449

大小= 10000,运行= 5000:ListToArray胜出 清单:20.094,ListToArray:14.453

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

1 个答案:

答案 0 :(得分:14)

  

这不是一个悖论吗?

没有

  

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

将列表转换为数组非常快

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

为什么这些事情是真的?

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

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

  

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

不,不。

  

我们应该预测这个案例。

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

  

每个&#34; For&#34;列表上的循环应该在启动之前自动调用.ToArray。

绝对不是。即使我们知道速度更快,但我们也不会担心,有很多种性能需要担心。 为了节省几毫秒而加倍使用的内存量直接影响了最小化内存使用的性能目标!并非所有人都关心原始速度。

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