In .NET, which loop runs faster, 'for' or

2018-12-31 09:04发布

In C#/VB.NET/.NET, which loop runs faster, for or foreach?

Ever since I read that a for loop works faster than a foreach loop a long time ago I assumed it stood true for all collections, generic collections, all arrays, etc.

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):

  1. for iterating an array of 1000+ strings - for is better than foreach
  2. for iterating over IList (non generic) strings - foreach is better than for

A few references found on the web for the same:

  1. Original grand old article by Emmanuel Schanzer
  2. CodeProject FOREACH Vs. FOR
  3. Blog - To foreach or not to foreach, that is the question
  4. ASP.NET forum - NET 1.1 C# for vs 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.

30条回答
若你有天会懂
2楼-- · 2018-12-31 09:05

Keep in mind that the for-loop and foreach-loop are not always equivalent. List enumerators will throw an exception if the list changes, but you won't always get that warning with a normal for loop. You might even get a different exception if the list changes at just the wrong time.

查看更多
笑指拈花
3楼-- · 2018-12-31 09:08

I wouldn't expect anyone to find a "huge" performance difference between the two.

I guess the answer depends on the whether the collection you are trying to access has a faster indexer access implementation or a faster IEnumerator access implementation. Since IEnumerator often uses the indexer and just holds a copy of the current index position, I would expect enumerator access to be at least as slow or slower than direct index access, but not by much.

Of course this answer doesn't account for any optimizations the compiler may implement.

查看更多
泪湿衣
4楼-- · 2018-12-31 09:09

There are very good reasons to prefer foreach loops over for loops. If you can use a foreach loop, your boss is right that you should.

However, not every iteration is simply going through a list in order one by one. If he is forbidding for, yes that is wrong.

If I were you, what I would do is turn all of your natural for loops into recursion. That'd teach him, and it's also a good mental exercise for you.

查看更多
浪荡孟婆
5楼-- · 2018-12-31 09:09

This is ridiculous. There's no compelling reason to ban the for-loop, performance-wise or other.

See Jon Skeet's blog for a performance benchmark and other arguments.

查看更多
不流泪的眼
6楼-- · 2018-12-31 09:09

"Are there any arguments I could use to help me convince him the for loop is acceptable to use?"

No, if your boss is micromanaging to the level of telling you what programming language constructs to use, there's really nothing you can say. Sorry.

查看更多
临风纵饮
7楼-- · 2018-12-31 09:10

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.

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.

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 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 (int i = 0; i < myCollection.Length, i++)
查看更多
登录 后发表回答