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

时间:2009-12-01 14:48:38

标签: c# performance arrays list ienumerable

  

可能重复:
  Is it better to call ToList() or ToArray() in LINQ queries?

我有这样的代码:

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
}

首选哪种方法?

我可以不用任何东西,但我需要知道尺寸,我不想打电话给Enumerable.Count<T>() - 它似乎会做更多的动作,然后Array<T>.SizeList<T>.Count。我是对的吗?

3 个答案:

答案 0 :(得分: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

所以基本上你可以获得相似的表现。

答案 1 :(得分: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;
}

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

答案 2 :(得分:11)

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

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