在.NET中,哪个循环运行得更快,“for”还是“foreach”?
在C#/ VB.NET / .NET中,哪个循环运行速度更快,是for
或foreach
?
自从我读了一个for
循环比foreach
循环的工作更快,很久以前我就认为它适用于所有集合,泛型集合,所有数组等等。
我搜索了谷歌并发现了一些文章,但其中大多数都没有结果(阅读文章的评论)并且是开放式的。
最理想的是将每个场景列出并提供相同的最佳解决方案。
例如(只是它应该如何的一个例子):
for
比foreach
更好 IList
(非泛型)字符串 - foreach
比for
更好 网上发现的一些相同的参考文献:
foreach
或不foreach
,这是个问题 for
vs foreach
[编辑]
除了可读性方面外,我对事实和数字非常感兴趣。 有一些应用程序的最后一英里的性能优化挤压很重要。
Patrick Smacchia在上个月发表了一篇博文,其结论如下:
foreach
循环展示超过特定意图for
循环 。
使用foreach
循环向任何使用你的代码的人展示了你正在计划对集合中的每个成员做些什么,而不管它在集合中的位置。 它也显示你不修改原始集合(如果你尝试去抛出异常)。
的另一个优点foreach
是,它适用于任何IEnumerable
,其中作为for
唯一有意义IList
,其中每个元素实际上有一个索引。
但是,如果您需要使用元素的索引,那么当然应该允许使用for
循环。 但是如果你不需要使用索引,那么只需要使用代码即可。
据我所知,没有显着的性能影响。 在未来的某个阶段,使用foreach
在多核上运行代码可能会更容易,但这不是现在需要担心的问题。
首先,对德米特里的答案提出反诉。 对于数组,C#编译器为foreach
发出的代码大体上与for
循环的等价物相同。 这就解释了为什么这个基准测试的结果基本相同:
using System;
using System.Diagnostics;
using System.Linq;
class Test
{
const int Size = 1000000;
const int Iterations = 10000;
static void Main()
{
double[] data = new double[Size];
Random rng = new Random();
for (int i=0; i < data.Length; i++)
{
data[i] = rng.NextDouble();
}
double correctSum = data.Sum();
Stopwatch sw = Stopwatch.StartNew();
for (int i=0; i < Iterations; i++)
{
double sum = 0;
for (int j=0; j < data.Length; j++)
{
sum += data[j];
}
if (Math.Abs(sum-correctSum) > 0.1)
{
Console.WriteLine("Summation failed");
return;
}
}
sw.Stop();
Console.WriteLine("For loop: {0}", sw.ElapsedMilliseconds);
sw = Stopwatch.StartNew();
for (int i=0; i < Iterations; i++)
{
double sum = 0;
foreach (double d in data)
{
sum += d;
}
if (Math.Abs(sum-correctSum) > 0.1)
{
Console.WriteLine("Summation failed");
return;
}
}
sw.Stop();
Console.WriteLine("Foreach loop: {0}", sw.ElapsedMilliseconds);
}
}
结果:
For loop: 16638
Foreach loop: 16529
接下来,验证Greg关于集合类型的观点是重要的 - 在上面将数组更改为List<double>
,并得到完全不同的结果。 一般来说,它不仅速度显着较慢,而且foreach比通过索引访问慢得多。 话虽如此,我仍然几乎总是喜欢foreach for一个for循环,它使代码更简单 - 因为可读性几乎总是很重要,而微型优化很少。
上一篇: In .NET, which loop runs faster, 'for' or 'foreach'?
下一篇: Why is my C++ text file parsing script so much slower than my Python script?