我需要迭代和计数.什么是最快或首选:ToArray()或ToList()?

aba*_*hev 17 c# arrays performance ienumerable list

可能重复:
在LINQ查询中调用ToList()或ToArray()会更好吗?

我有这样的代码:

void Foobar(string[] arr, Dictionary<string, string[]>)
{
   var t = arr.Intersect(dic.Keys).ToList(); // .or ToArray() ?
   foreach(var item in t)
   {
      ..
   }

   var j = t.Count; // also I need this
}
Run Code Online (Sandbox Code Playgroud)

哪种方法更受欢迎?

我可以没有任何东西,但我需要知道大小,我不想打电话Enumerable.Count<T>()- 似乎做了更多的行动然后Array<T>.SizeList<T>.Count.我对吗?

Yan*_*rtz 16

实际上,在Count(IEnumerable)的当前MS实现中,有一个快捷方式,查看IEnumerable是否为ICollection并在其上调用Count.因此,计数元素的性能应具有可比性.

ToList和ToArray有点相同.如果IEnumerable是ICollection,则会调用CopyTo方法,这会更快一些.

因此,选择使您的代码最具可读性的内容,并为您的用例制定基准以获得明确的答案.

更新:我做了一个天真的基准测试.

从数组开始: var items = Enumerable.Range(1,1000).ToArray();

  • 调用ToList():25ms/10000
  • 调用ToArray():23 ms/10000

从IEnumerable开始: var items = Enumerable.Range(1,1000);

  • 调用ToList():168ms/10000
  • 调用ToArray():171 ms/10000

所以基本上你获得了可比的表现


Gre*_*reg 12

如果你真的关心性能,你应该循环IEnumerable并计算它.这避免了必须完全创建一个新集合,并且交集只需要迭代一次:

void Foobar(string[] arr, Dictionary<string, string[]>)
{
   var t = arr.Intersect(dic.Keys);
   int count = 0;
   foreach(var item in t)
   {
      count++;
      ..
   }

   var j = count;
}
Run Code Online (Sandbox Code Playgroud)

但就像别人说的那样:这种气味微观优化.如果在这种情况下性能真的很重要,至少要进行性能分析,找出哪种方法对您来说真的最快.

  • @Yaakov:有必要计算集合的大小.通过计算自己,你只需要迭代一次收集.如果集合被转换为列表数组,则集合必须至少进行两次交互(一次用于转换,一次用于`foreach`循环. (5认同)
  • @Yaakov:不,重点是从枚举中创建数组或列表会导致创建迭代.然后,您必须遍历已创建的数组或列表上正在进行的任何处理.相反,只需枚举集合计数和处理即可. (2认同)

Yaa*_*lis 11

差异可能很小,所以值得使用更符合您需求的方法.微优化的气味.

在这种情况下,由于您所做的只是枚举集合并计算集合(两者都可以使用IEnumerable),为什么不将它留作IEnumerable <>?