C# 在 .NET 中,哪个循环运行得更快,“for”还是“foreach”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/365615/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In .NET, which loop runs faster, 'for' or 'foreach'?
提问by Binoj Antony
In C#/VB.NET/.NET, which loop runs faster, for
or foreach
?
在 C#/VB.NET/.NET 中,哪个循环运行得更快,for
或者foreach
?
Ever since I read that a for
loop works faster than a foreach
loop a long time agoI assumed it stood true for all collections, generic collections, all arrays, etc.
自从我读了一个for
循环工程快于foreach
环路很久以前我以为这对所有集合,泛型集合,所有阵列,等真正站在
I scoured Google and found a few articles, but most of them are inconclusive (read comments on the articles) and open ended.
我在谷歌上搜索并找到了一些文章,但大多数都没有定论(阅读文章的评论)并且是开放式的。
What would be ideal is to have each scenario listed and the best solution for the same.
理想的做法是列出每个场景并为其提供最佳解决方案。
For example (just an example of how it should be):
例如(只是它应该如何的一个例子):
- for iterating an array of 1000+
strings -
for
is better thanforeach
- for iterating over
IList
(non generic) strings -foreach
is better thanfor
- 迭代 1000 多个字符串的数组 -
for
比foreach
- 用于迭代
IList
(非通用)字符串 -foreach
比for
A few references found on the web for the same:
在网上找到了一些相同的参考资料:
- Original grand old article by Emmanuel Schanzer
- CodeProject FOREACH Vs. FOR
- Blog - To
foreach
or not toforeach
, that is the question - ASP.NET forum - NET 1.1 C#
for
vsforeach
- Emmanuel Schanzer 的原创盛大旧文章
- CodeProject FOREACH Vs。为了
- 博客 - 去
foreach
还是不去foreach
,这是个问题 - ASP.NET 论坛 - NET 1.1 C#
for
与foreach
[Edit]
[编辑]
Apart from the readability aspect of it, I am really interested in facts and figures. There are applications where the last mile of performance optimization squeezed do matter.
除了它的可读性方面,我对事实和数据非常感兴趣。在某些应用程序中,最后一英里的性能优化很重要。
采纳答案by Ian Nelson
Patrick Smacchia blogged about thislast month, with the following conclusions:
Patrick Smacchia 上个月在博客中谈到了这一点,并得出以下结论:
- for loops on List are a bit more than 2 times cheaper than foreach loops on List.
- Looping on array is around 2 times cheaper than looping on List.
- As a consequence, looping on array using for is 5 times cheaper than looping on List using foreach (which I believe, is what we all do).
- List 上的 for 循环比 List 上的 foreach 循环便宜 2 倍多。
- 在数组上循环比在 List 上循环便宜大约 2 倍。
- 因此,使用 for 在数组上循环比使用 foreach 在 List 上循环便宜 5 倍(我相信,这是我们都做的)。
回答by Brian Rasmussen
My guess is that it will probably not be significant in 99% of the cases, so why would you choose the faster instead of the most appropriate (as in easiest to understand/maintain)?
我的猜测是在 99% 的情况下它可能并不重要,那么为什么您会选择更快的而不是最合适的(最容易理解/维护)?
回答by Marc Gravell
It will always be close. For an array, sometimesfor
is slightly quicker, but foreach
is more expressive, and offers LINQ, etc. In general, stick with foreach
.
它会一直很近。对于数组,有时for
稍微快一点,但foreach
更具表现力,并提供 LINQ 等。一般来说,坚持使用foreach
.
Additionally, foreach
may be optimised in some scenarios. For example, a linked list might be terrible by indexer, but it might be quick by foreach
. Actually, the standard LinkedList<T>
doesn't even offer an indexer for this reason.
此外,foreach
在某些情况下可能会进行优化。例如,一个链表对于索引器来说可能很糟糕,但它可能很快foreach
。实际上,LinkedList<T>
出于这个原因,该标准甚至没有提供索引器。
回答by Oliver Friedrich
I did test it a while ago, with the result that a for
loop is much faster than a foreach
loop. The cause is simple, the foreach
loop first needs to instantiate an IEnumerator
for the collection.
不久前我确实对其进行了测试,结果是for
循环比foreach
循环快得多。原因很简单,foreach
循环首先需要IEnumerator
为集合实例化一个。
回答by Tarik
for has more simple logic to implement so it's faster than foreach.
for 有更简单的逻辑来实现,所以它比 foreach 更快。
回答by Alex York
The differences in speed in a for
- and a foreach
-loop are tiny when you're looping through common structures like arrays, lists, etc, and doing a LINQ
query over the collection is almost always slightly slower, although it's nicer to write! As the other posters said, go for expressiveness rather than a millisecond of extra performance.
当您循环遍历数组、列表等常见结构时,for
- 和 -foreach
循环中的速度差异很小,并且LINQ
对集合进行查询几乎总是稍微慢一点,尽管编写起来更好!正如其他海报所说,追求表现力而不是一毫秒的额外表现。
What hasn't been said so far is that when a foreach
loop is compiled, it is optimised by the compiler based on the collection it is iterating over. That means that when you're not sure which loop to use, you should use the foreach
loop - it will generate the best loop for you when it gets compiled. It's more readable too.
到目前为止还没有说的是,当一个foreach
循环被编译时,编译器会根据它迭代的集合对其进行优化。这意味着当您不确定要使用哪个循环时,您应该使用该foreach
循环 - 它会在编译时为您生成最佳循环。它也更具可读性。
Another key advantage with the foreach
loop is that if your collection implementation changes (from an int array
to a List<int>
for example) then your foreach
loop won't require any code changes:
foreach
循环的另一个关键优势是,如果您的集合实现发生更改(例如从 int 更改array
为 a List<int>
),那么您的foreach
循环将不需要任何代码更改:
foreach (int i in myCollection)
The above is the same no matter what type your collection is, whereas in your for
loop, the following will not build if you changed myCollection
from an array
to a List
:
无论您的集合是什么类型,以上内容都是相同的,而在您的for
循环中,如果您myCollection
从 an更改array
为 a ,则不会构建以下内容List
:
for (int i = 0; i < myCollection.Length, i++)
回答by Andrew Kennan
It probably depends on the type of collection you are enumerating and the implementation of its indexer. In general though, using foreach
is likely to be a better approach.
这可能取决于您枚举的集合类型及其索引器的实现。但总的来说,使用foreach
可能是更好的方法。
Also, it'll work with any IEnumerable
- not just things with indexers.
此外,它可以与任何IEnumerable
东西一起使用——而不仅仅是索引器的东西。
回答by Greg Hewgill
There is unlikely to be a huge performance difference between the two. As always, when faced with a "which is faster?" question, you should always think "I can measure this."
两者之间不太可能存在巨大的性能差异。与往常一样,当面临“哪个更快?” 问题,你应该总是想“我可以衡量这个”。
Write two loops that do the same thing in the body of the loop, execute and time them both, and see what the difference in speed is. Do this with both an almost-empty body, and a loop body similar to what you'll actually be doing. Also try it with the collection type that you're using, because different types of collections can have different performance characteristics.
在循环体中写两个做同样事情的循环,执行它们并计时,看看速度有什么不同。使用几乎为空的主体和类似于您实际要做的循环主体来执行此操作。还可以尝试使用您正在使用的集合类型,因为不同类型的集合可能具有不同的性能特征。
回答by Jon Skeet
First, a counter-claim to Dmitry's (now deleted) answer. For arrays, the C# compiler emits largely the same code for foreach
as it would for an equivalent for
loop. That explains why for this benchmark, the results are basically the same:
首先,对德米特里(现已删除)的回答提出反诉。对于数组,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);
}
}
Results:
结果:
For loop: 16638
Foreach loop: 16529
Next, validation that Greg's point about the collection type being important - change the array to a List<double>
in the above, and you get radically different results. Not only is it significantly slower in general, but foreach becomes significantly slower than accessing by index. Having said that, I would still almost alwaysprefer foreach to a for loop where it makes the code simpler - because readability is almost always important, whereas micro-optimisation rarely is.
接下来,验证 Greg 关于集合类型很重要的观点 - 将数组更改List<double>
为上面的 a,您会得到完全不同的结果。它不仅在一般情况下明显变慢,而且 foreach 变得比通过索引访问慢得多。话虽如此,我仍然几乎总是更喜欢 foreach 而不是 for 循环,因为它使代码更简单 - 因为可读性几乎总是很重要,而微优化很少。