【发布时间】:2011-11-26 17:53:50
【问题描述】:
我注意到迭代已转换为通用接口集合(IList 或 IEnumberable)的原始集合 (T[]) 会降低性能。
例如:
private static int Sum(int[] array)
{
int sum = 0;
foreach (int i in array)
sum += i;
return sum;
}
上面的代码执行速度明显快于下面的代码,其中参数更改为 IList 类型(或 IEnumerable):
private static int Sum(IList<int> array)
{
int sum = 0;
foreach (int i in array)
sum += i;
return sum;
}
如果传递的对象是原始数组,并且我尝试将循环更改为 for 循环而不是 foreach 循环,性能仍然会受到影响。
我可以通过这样的编码来解决性能问题:
private static int Sum(IList<int> array)
{
int sum = 0;
if( array is int[] )
foreach (int i in (int[])array)
sum += i;
else
foreach (int i in array)
sum += i;
return sum;
}
有没有更优雅的方法来解决这个问题?感谢您的宝贵时间。
编辑:我的基准代码:
static void Main(string[] args)
{
int[] values = Enumerable.Range(0, 10000000).ToArray<int>();
Stopwatch sw = new Stopwatch();
sw.Start();
Sum(values);
//Sum((IList<int>)values);
sw.Stop();
Console.WriteLine("Elasped: {0} ms", sw.ElapsedMilliseconds);
Console.Read();
}
【问题讨论】:
-
你是如何衡量这个的?如果你在循环中重复运行代码,VM可能会动态优化它。
-
我没有在虚拟机中运行它。我会将我的简单基准代码添加到问题中。
-
我还会考虑三元 for 循环并使用索引器进行交互。有趣...
-
性能会受到多大影响?通常在实践中,这种性能差异对实际处理部分没有任何意义。我敢肯定,在你的实际项目中,你不会做简单的 sum+=i,任何更高级的处理都会比 IList
迭代花费更长的时间,即使它确实比 int[] 迭代需要更多的时间。跨度> -
我自己检查了速度。看起来,有一个表演命中,它是戏剧性的100%!!!! :) 对于 100000000 个 int 数组,在我的 Core 2 Duo E8200 上需要 1.2 秒,而 IList
需要 2.4 秒。我真的会忘记这种差异。 PS 我在调试时使用了作者提供的方法。
标签: c# performance generics collections