386

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.

Callum Watkins
  • 2,444
  • 2
  • 27
  • 42
Binoj Antony
  • 15,352
  • 24
  • 86
  • 95
  • 3
    The difference still exists. Arrays in particular should be just as fast under foreach, but for everything else, plain loops are faster. Of course, most of the time, this won't make a difference, and of course, a clever JIT compiler could in theory eliminate the difference. – jalf Dec 13 '08 at 22:53
  • 1
    I see three solutions: (1) Write a compiler that enumerates in random order (2) rename "foreach" to "ForEachInStrictOrder (3) Rename ourselves to ~Ian perhaps Iain? – Ian Hopkinson Jan 23 '09 at 09:58
  • 3
    Without context, I can't know exactly what you're doing, but what happens when you come across a partially filled array? – Chris Cudmore Dec 22 '09 at 15:18
  • 6
    By the way, 2 million hits/month is nothing scary. It's less than a hit per second on average. – mmx Dec 22 '09 at 15:46
  • See also http://stackoverflow.com/questions/1723855/ienumerable-question-best-performance/1724054#1724054 – Wim Coenen Dec 22 '09 at 16:43
  • What I have learned from posting my thread (which ended up being a very beneficial insight for me) is that you should use a foreach when you don't need to reference an index in the collection. Otherwise use a for. That's one good decision point – PositiveGuy Dec 23 '09 at 21:38
  • 40
    **Important Note**: This question got merged yesterday with a totally unrelated question about being forced to use `foreach` instead of `for` in C#. If you see answers here that make no sense at all, that is why. Blame the moderator, not the hapless answers. – T.E.D. May 27 '10 at 13:35
  • 1
    In general for would be faster then foreach. However if you care you've probably got "other problems" which are of higher importance... – Thomas Hansen Feb 17 '09 at 17:04
  • 8
    @T.E.D. Oh I was wondering where all the "your boss is an idiot" comments where coming from, thanks – Gaspa79 Jul 21 '16 at 17:27
  • Related [Performance difference for control structures 'for' and 'foreach' in C#](https://stackoverflow.com/questions/1124753/performance-difference-for-control-structures-for-and-foreach-in-c-sharp) – Theraot Jun 19 '19 at 20:06

41 Answers41

398

Patrick Smacchia blogged about this last month, with the following conclusions:

  • 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).
Ian Nelson
  • 51,299
  • 20
  • 72
  • 100
  • 143
    However, never forget: "Premature optimization is the root of all evil." – Oorang May 29 '09 at 04:53
  • 22
    @Hardwareguy: Once you know that for is almost imperceptably faster, why shouldn't you start using it in general? It doesn't take extra time. – DevinB Sep 03 '09 at 13:06
  • 55
    @devinb, using "for" is harder than using "foreach" as it adds code, another variable, a condition you need to check, etc. How many times have you seen an off-by-one error in a "foreach" loop? – tster Dec 03 '09 at 15:45
  • 39
    @Hardwareguy, let me see if I got this straight. It takes 5 times longer to loop through a list with `foreach` than it does to loop through an array with `for`, and you're calling that insignificant? That kind of a performance difference might matter for your application, and it might not, but I wouldn't just dismiss it out of hand. – Robert Harvey Dec 23 '09 at 00:04
  • 49
    Reading through the blog post it looks like the tests were run in Debug and not Release so that might have a factor. Additionally the difference is specifically for just the loop overhead. It doesn't affect the time to execute the body of the loop at all which is most cases is much longer than the time it takes to move to the next element of the list. It's good information to know when you've identified that there clearly is a problem and you've measured the difference in your app specifically and there's a noticeable improvement but definitely not general advice to remove all `foreach`s. – Davy8 May 27 '10 at 13:26
  • 6
    `foreach` can be way cheaper then `for loop` with `LinkedList` – gdoron is supporting Monica Jan 17 '12 at 06:53
  • 3
    the images within that link are broken, here's the archived copy http://web.archive.org/web/20140827024150/http://codebetter.com/patricksmacchia/2008/11/19/an-easy-and-efficient-way-to-improve-net-code-performances/ – Tony Feb 26 '15 at 21:14
  • 1
    @Davy8 I have check current results in release mode using Stopwatch. The results have changed since that article was written. 1. List loop is almost 7 times faster than foreach loop. 100 000 000^2 iterations were performed. For with optimized count is the fastest, but the is almost no difference with the example without optimization (for no optimization: 326; for count optimized: 296; foreach 2356). 2. But, what is more interesting. In some cases for a int[] foreach is a little faster than for (for no optimization: 294; for count optimized: 294; foreach 267, less!). 10^8^2 opers as well. – Anton Lyhin Nov 08 '15 at 17:36
  • @gdoron I know you were referring to including an index lookup, but a `for (n = l.First; n != null; n = n.Next)` loop is about halfway between a `foreach` loop and the corresponding array-based `for`loop. – Mark Hurd Jun 01 '16 at 16:05
  • 1
    can't you replace cheaper with faster(if that's what you mean). it'd be clearer – barlop Sep 23 '16 at 05:48
  • @Ian Nelson: In jacksondunstan article, ForEach - Assignment is not done . I had change the code and executed as you mentioned the results was not changed... Thanks :-0) – Thulasiram Jul 04 '17 at 11:44
  • 2
    Is it worth adding a qualifier on this answer; i.e. switching from `foreach` on a list to `for` on an array will not (in most cases) improve your code's performance by 5x as implied. If all you were doing was looping that would be true, but then you could improve performance infinitely by skipping the loop altogether. If you have code within the loop, that will still take just as long to process, and will still process once per iteration , typically making the benefit of the `for` loop fairly negligible by comparison. – JohnLBevan Jul 07 '17 at 09:08
171

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:

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 always prefer foreach to a for loop where it makes the code simpler - because readability is almost always important, whereas micro-optimisation rarely is.

TylerH
  • 19,065
  • 49
  • 65
  • 86
Jon Skeet
  • 1,261,211
  • 792
  • 8,724
  • 8,929
  • "change the array to a List in the above, and you get radically different results" Very interesting, I hadn't thought about that – johnc Jan 23 '09 at 10:12
  • 5
    Given the strange differences in results between my tests and other people's benchmarks, I think this is going to merit a blog post... – Jon Skeet Jan 23 '09 at 10:19
  • 1
    Which do you *almost always* prefer between arrays and `List`? Does readability trump micro-optimization in that case too? – JohnB May 27 '10 at 16:18
  • 14
    @JohnB: Yup - I almost always prefer `List` over arrays. The exceptions are `char[]` and `byte[]` which are more often treated as "chunks" of data rather than normal collections. – Jon Skeet May 27 '10 at 16:38
  • Amazing, I'm getting even more aggressive difference on my machine, almost 10% in favor of foreach on simple arrays. I'm guessing wildly that this all stems from the jitter not have to worry about the extra variable, bound checks, etc.. would be very interesting if someone has a deep explanation of this. – Tamir Daniely Jun 30 '19 at 21:00
162

foreach loops demonstrate more specific intent than for loops.

Using a foreach loop demonstrates to anyone using your code that you are planning to do something to each member of a collection irrespective of its place in the collection. It also shows you aren't modifying the original collection (and throws an exception if you try to).

The other advantage of foreach is that it works on any IEnumerable, where as for only makes sense for IList, where each element actually has an index.

However, if you need to use the index of an element, then of course you should be allowed to use a for loop. But if you don't need to use an index, having one is just cluttering your code.

There are no significant performance implications as far as I'm aware. At some stage in the future it might be easier to adapt code using foreach to run on multiple cores, but that's not something to worry about right now.

ctford
  • 7,009
  • 4
  • 31
  • 51
  • This is very helpful when iterating through a custom object list or datalist and not have to worry about all the index nomenclature when processing the data. – Dillie-O Dec 22 '09 at 15:34
  • I can't see how `foreach` helps multithreading. I guess you are referring to things like Task Parallel Library but that's not really a magic of `foreach`. – mmx Dec 22 '09 at 15:49
  • @Mehrdad The compiler has freedom on how to iterate through the list with foreach. For example, it could iterate through the the even elements on one core and the odd elements on another. foreach is closer to the functional style of programming. – ctford Dec 22 '09 at 15:51
  • 24
    ctford: No it's not. The compiler certainly cannot reorder elements in `foreach`. `foreach` is not at all related to functional programming. It's **totally** an imperative paradigm of programming. You are mis-attributing things happening in TPL and PLINQ to `foreach`. – mmx Dec 22 '09 at 15:53
  • 1
    @Mehrdad,ctford: I guess it depends if foreach has a guarantee of order. If foreach has no guarantee of order it could be optimized by a future version of the compiler to use the cores if there is something like an attribute to mark the code within the foreach loop as thread-safe ? – BlueTrin Dec 22 '09 at 16:05
  • 14
    @BlueTrin: It certainly does guarantee ordering (C# spec section 8.8.4 formally defines `foreach` as an equivalent of a `while` loop). I think I know @ctford is referring to. Task parallel library allows **the underlying collection** to provide elements in an arbitrary order (by calling `.AsParallel` on an enumerable). `foreach` doesn't do anything here and the body of the loop is executed on a **single thread**. The only thing that is parallelized is the generation of the sequence. – mmx Dec 22 '09 at 16:11
  • 2
    @Mehrdad: Also, using foreach helps to avoid coupling your element processing code with any concept of ordering, thus making it more easily paralisable in the future. I overstated my point - foreach is not map. – ctford Dec 22 '09 at 16:17
  • `foreach` actually works with any IEnumerable-"like" object (not a correction to your post as much as an interesting note about duck typing): http://blogs.msdn.com/kcwalina/archive/2007/07/18/DuckNotation.aspx – Sam Harwell Dec 22 '09 at 16:25
  • 6
    Enumerable.Select has an overload that lets you obtain the index of the item, so even the need for an index does not mandate using for. See http://msdn.microsoft.com/en-us/library/bb534869.aspx – TrueWill Dec 22 '09 at 18:16
  • 5
    ForEach is handy for readability and saving typing. Costs matter, though; changing 2 or 3 for-loops in a document designer UI that I made, from (for each obj in list) to (for i=0 to list.count-1) reduced response time from 2-3 sec per edit to about .5 sec per edit on a small document just looping thru a few hundred objects. Now for even huge documents, there is no increase in time to loop all. I have no idea how this happened. What I do know is that the alternative was a complicated scheme to only loop a subset of the objects. I'll take the 5 minute change any day! - _not_ micro-optimisation. – FastAl Mar 31 '11 at 13:37
  • 5
    @FastAl The difference between `foreach` and `for` performance for normal lists is fractions of a second for iterating over millions of items so your issue certainly wasn't directly related to foreach performance, at least not for a few hundred objects. Sounds like a broken enumerator implementation in whatever list you were using. – Mike Marynowski Nov 26 '17 at 01:38
53

Any time there's arguments over performance, you just need to write a small test so that you can use quantitative results to support your case.

Use the StopWatch class and repeat something a few million times, for accuracy. (This might be hard without a for loop):

using System.Diagnostics;
//...
Stopwatch sw = new Stopwatch()
sw.Start()
for(int i = 0; i < 1000000;i ++)
{
    //do whatever it is you need to time
}
sw.Stop();
//print out sw.ElapsedMilliseconds

Fingers crossed the results of this show that the difference is negligible, and you might as well just do whatever results in the most maintainable code

pikachu
  • 991
  • 2
  • 10
  • 20
Rob Fonseca-Ensor
  • 15,227
  • 41
  • 56
  • 13
    But you can't compare performance of for and foreach. They are supposed to be used in different circumstances. – Michael Krelin - hacker Dec 22 '09 at 15:11
  • 7
    I agree with you Michael, you shouldn't choose which one to use based on performance - you should choose the one that makes the most sense! But if your boss says "Don't use for because it's slower than foreach" then this is the only way to convince him that the difference is negligible – Rob Fonseca-Ensor Dec 22 '09 at 15:19
  • "(This might be hard without a for loop)" Or you can use a while loop. – jonescb Dec 22 '09 at 18:42
50

It will always be close. For an array, sometimes for is slightly quicker, but foreach is more expressive, and offers LINQ, etc. In general, stick with 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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Marc Gravell
  • 927,783
  • 236
  • 2,422
  • 2,784
  • So are you saying `LinkedList` is leaner than `List`? And if I'm always going to be using `foreach` (instead of `for`), I'm better off using `LinkedList`? – JohnB May 26 '10 at 20:00
  • 2
    @JohnB - not leaner; just different. For example, each node in a linked list has additional references that aren't needed for a flat array (which also underpins `List`). It is more that it is cheaper to *insert* / *remove*. – Marc Gravell May 26 '10 at 21:37
36

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

Brian Rasmussen
  • 109,816
  • 33
  • 208
  • 305
  • 6
    @klew, If you actually profile your code you wouldn't have to guess which 20% need to be as fast as possible. You would probably also find out that the actual number of loops which need to be fast is much lower. Furthermore, are you really saying that the act of looping is where you spend your time, as opposed to what you actually do in that loop? – tster Dec 03 '09 at 15:47
32

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
T.E.D.
  • 41,324
  • 8
  • 64
  • 131
  • How does recursion compare to `for` loops and `foreach` loops performance-wise? – JohnB May 27 '10 at 05:18
  • It depends. If you use tail-recursion and your compiler is smart enough to notice, it can be identical. OTOH: If it doesn't and you do something stupid like pass a lot of unnessecary (unchanging) data as parameters or declare big structures on the stack as locals, it can be really really slow (or even run out of RAM). – T.E.D. May 27 '10 at 12:55
  • Ahhh. I see why you asked that now. This answer went to a totally different question. For some bizzare reason Jonathan Sampson merged the two yesterday. He really shouldn't have done that. The merged answers will make no sense here whatsoever. – T.E.D. May 27 '10 at 13:02
32

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.

Greg Hewgill
  • 828,234
  • 170
  • 1,097
  • 1,237
18

Jeffrey Richter on TechEd 2005:

"I have come to learn over the years the C# compiler is basically a liar to me." .. "It lies about many things." .. "Like when you do a foreach loop..." .. "...that is one little line of code that you write, but what the C# compiler spits out in order to do that it's phenomenal. It puts out a try/finally block in there, inside the finally block it casts your variable to an IDisposable interface, and if the cast suceeds it calls the Dispose method on it, inside the loop it calls the Current property and the MoveNext method repeatedly inside the loop, objects are being created underneath the covers. A lot of people use foreach because it's very easy coding, very easy to do.." .. "foreach is not very good in terms of performance, if you iterated over a collection instead by using square bracket notation, just doing index, that's just much faster, and it doesn't create any objects on the heap..."

On-Demand Webcast: http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032292286&EventCategory=3&culture=en-US&CountryCode=US

Max Toro
  • 27,264
  • 10
  • 71
  • 109
12

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.

Rik
  • 26,673
  • 13
  • 47
  • 65
  • 2
    Updated link: http://codeblog.jonskeet.uk/2009/01/29/for-vs-foreach-on-arrays-and-lists/ – Matt Oct 27 '15 at 16:11
  • The loop construct that is faster depends on what you need to iterate over. [Another blog that benchmarks multiple iterations over multiple kinds of objects](http://cc.davelozinski.com/c-sharp/for-vs-foreach-vs-while), such as DataRows and custom objects. It also includes the performance of the While loop construct and not just the for and foreach looping constructs. – Free Coder 24 May 20 '16 at 07:10
12

you can read about it in Deep .NET - part 1 Iteration

it's cover the results (without the first initialization) from .NET source code all the way to the disassembly.

for example - Array Iteration with a foreach loop: enter image description here

and - list iteration with foreach loop: enter image description here

and the end results: enter image description here

enter image description here

Or Yaacov
  • 2,880
  • 3
  • 15
  • 39
11

In cases where you work with a collection of objects, foreach is better, but if you increment a number, a for loop is better.

Note that in the last case, you could do something like:

foreach (int i in Enumerable.Range(1, 10))...

But it certainly doesn't perform better, it actually has worse performance compared to a for.

AustinWBryan
  • 2,968
  • 3
  • 17
  • 35
Meta-Knight
  • 16,753
  • 44
  • 57
  • "Better" is debateable: It is slower and the dnspy debugger won't break into a C# foreach (although VS2017 debugger will). Sometimes more readable but if you support languages without it, it can be annoying. – Zeek2 Jul 26 '18 at 09:21
10

This should save you:

public IEnumerator<int> For(int start, int end, int step) {
    int n = start;
    while (n <= end) {
        yield n;
        n += step;
    }
}

Use:

foreach (int n in For(1, 200, 4)) {
    Console.WriteLine(n);
}

For greater win, you may take three delegates as parameters.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
akuhn
  • 25,901
  • 2
  • 72
  • 86
  • 1
    One tiny difference is that a `for` loop is usually written to exclude the end of the range (e.g. `0 <= i < 10`). `Parallel.For` also does that to keep it easily interchangeable with a common `for` loop. – Groo Jul 24 '14 at 19:42
9

This has the same two answers as most "which is faster" questions:

1) If you don't measure, you don't know.

2) (Because...) It depends.

It depends on how expensive the "MoveNext()" method is, relative to how expensive the "this[int index]" method is, for the type (or types) of IEnumerable that you will be iterating over.

The "foreach" keyword is shorthand for a series of operations - it calls GetEnumerator() once on the IEnumerable, it calls MoveNext() once per iteration, it does some type checking, and so on. The thing most likely to impact performance measurements is the cost of MoveNext() since that gets invoked O(N) times. Maybe it's cheap, but maybe it's not.

The "for" keyword looks more predictable, but inside most "for" loops you'll find something like "collection[index]". This looks like a simple array indexing operation, but it's actually a method call, whose cost depends entirely on the nature of the collection that you're iterating over. Probably it's cheap, but maybe it's not.

If the collection's underlying structure is essentially a linked list, MoveNext is dirt-cheap, but the indexer might have O(N) cost, making the true cost of a "for" loop O(N*N).

NSFW
  • 459
  • 4
  • 12
8

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++)
Alex York
  • 5,282
  • 2
  • 29
  • 27
7

"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.

Ken
  • 427
  • 7
  • 10
7

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.

Also, it'll work with any IEnumerable - not just things with indexers.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Andrew Kennan
  • 13,207
  • 3
  • 22
  • 33
6

Every language construct has an appropriate time and place for usage. There is a reason the C# language has a four separate iteration statements - each is there for a specific purpose, and has an appropriate use.

I recommend sitting down with your boss and trying to rationally explain why a for loop has a purpose. There are times when a for iteration block more clearly describes an algorithm than a foreach iteration. When this is true, it is appropriate to use them.

I'd also point out to your boss - Performance is not, and should not be an issue in any practical way - it's more a matter of expression the algorithm in a succinct, meaningful, maintainable manner. Micro-optimizations like this miss the point of performance optimization completely, since any real performance benefit will come from algorithmic redesign and refactoring, not loop restructuring.

If, after a rational discussion, there is still this authoritarian view, it is up to you as to how to proceed. Personally, I would not be happy working in an environment where rational thought is discouraged, and would consider moving to another position under a different employer. However, I strongly recommend discussion prior to getting upset - there may just be a simple misunderstanding in place.

Reed Copsey
  • 522,342
  • 70
  • 1,092
  • 1,340
5

Whether for is faster than foreach is really besides the point. I seriously doubt that choosing one over the other will make a significant impact on your performance.

The best way to optimize your application is through profiling of the actual code. That will pinpoint the methods that account for the most work/time. Optimize those first. If performance is still not acceptable, repeat the procedure.

As a general rule I would recommend to stay away from micro optimizations as they will rarely yield any significant gains. Only exception is when optimizing identified hot paths (i.e. if your profiling identifies a few highly used methods, it may make sense to optimize these extensively).

Brian Rasmussen
  • 109,816
  • 33
  • 208
  • 305
  • If the only kind of optimization I needed to do in the projects I work on were micro optimizations, I would a happy camper. Sadly, this is never the case. – Yannick Motton Dec 22 '09 at 15:43
  • 2
    `for` is marginally faster than `foreach`. I'd seriously object to this statement. That totally depends on the underlying collection. If a linked list class provides an indexer with an integer parameter, I would expect using a `for` loop on it to be O(n^2) while `foreach` is expected to be O(n). – mmx Dec 22 '09 at 16:17
  • @Merhdad: Actually that is a good point. I was just thinking about the regular case of indexing a list (i.e. array). I'll reword to reflect that. Thanks. – Brian Rasmussen Dec 22 '09 at 16:50
  • @Mehrdad Afshari: Indexing a collection by integer may be *much* slower than enumerating over it. But you are actually comparing using `for` **and** an indexer lookup to using `foreach` by itself. I think @Brian Rasmussen's answer is correct that, aside from any use with a collection, `for` will always be slightly faster than `foreach`. However, `for` plus a collection lookup will always be slower than `foreach` by itself. – Daniel Pryden Dec 22 '09 at 16:52
  • @Daniel: Either you have a plain array, for which both will generate identical code, or there's an indexer involved when you use `for` statement. Plain `for` loop with an integer control variable is not comparable to `foreach`, so that's out. I understand what @Brian means and it's correct as you say but the answer can be misleading. Re: your last point: no, actually, `for` over `List` is still faster than `foreach`. – mmx Dec 22 '09 at 16:59
  • @Mehrdad- Surely with a LinkedList you'd write something like for(var node= list.Head; node != null; node = node.Next) if you wanted to use a for loop, making it O(n). – RichardOD Dec 23 '09 at 09:06
  • @RichardOD: The linked list class I was imagining abstracts away the nodes from you and you can either access items with a number, or with `foreach` ;) Anyway, my point is, strictly speaking, without knowing the underlying collection and the way it works, you can't say one is faster than another. It's like saying method `A()` is faster than `B()` without having an idea what they are doing. – mmx Dec 23 '09 at 19:50
5

It is what you do inside the loop that affects perfomance, not the actual looping construct (assuming your case is non-trivial).

Martin Wickman
  • 18,530
  • 10
  • 71
  • 97
4

The two will run almost exactly the same way. Write some code to use both, then show him the IL. It should show comparable computations, meaning no difference in performance.

cjk
  • 43,338
  • 9
  • 74
  • 109
3

It seems a bit strange to totally forbid the use of something like a for loop.

There's an interesting article here that covers a lot of the performance differences between the two loops.

I would say personally I find foreach a bit more readable over for loops but you should use the best for the job at hand and not have to write extra long code to include a foreach loop if a for loop is more appropriate.

colethecoder
  • 1,089
  • 1
  • 8
  • 26
  • Essential quote form the article you link to: "...if you are planning to write high performance code that is not for collections, use for loop. Even for collections, foreach may look handy when using, but it's not that efficient. " – NickFitz Dec 22 '09 at 16:54
3

In most cases there's really no difference.

Typically you always have to use foreach when you don't have an explicit numerical index, and you always have to use for when you don't actually have an iterable collection (e.g. iterating over a two-dimensional array grid in an upper triangle). There are some cases where you have a choice.

One could argue that for loops can be a little more difficult to maintain if magic numbers start to appear in the code. You should be right to be annoyed at not being able to use a for loop and have to build a collection or use a lambda to build a subcollection instead just because for loops have been banned.

Cade Roux
  • 83,561
  • 38
  • 170
  • 259
3

You can really screw with his head and go for an IQueryable .foreach closure instead:

myList.ForEach(c => Console.WriteLine(c.ToString());
TylerH
  • 19,065
  • 49
  • 65
  • 86
Tad Donaghe
  • 6,610
  • 1
  • 27
  • 62
3

I found the foreach loop which iterating through a List faster. See my test results below. In the code below I iterate an array of size 100, 10000 and 100000 separately using for and foreach loop to measure the time.

enter image description here

private static void MeasureTime()
    {
        var array = new int[10000];
        var list = array.ToList();
        Console.WriteLine("Array size: {0}", array.Length);

        Console.WriteLine("Array For loop ......");
        var stopWatch = Stopwatch.StartNew();
        for (int i = 0; i < array.Length; i++)
        {
            Thread.Sleep(1);
        }
        stopWatch.Stop();
        Console.WriteLine("Time take to run the for loop is {0} millisecond", stopWatch.ElapsedMilliseconds);

        Console.WriteLine(" ");
        Console.WriteLine("Array Foreach loop ......");
        var stopWatch1 = Stopwatch.StartNew();
        foreach (var item in array)
        {
            Thread.Sleep(1);
        }
        stopWatch1.Stop();
        Console.WriteLine("Time take to run the foreach loop is {0} millisecond", stopWatch1.ElapsedMilliseconds);

        Console.WriteLine(" ");
        Console.WriteLine("List For loop ......");
        var stopWatch2 = Stopwatch.StartNew();
        for (int i = 0; i < list.Count; i++)
        {
            Thread.Sleep(1);
        }
        stopWatch2.Stop();
        Console.WriteLine("Time take to run the for loop is {0} millisecond", stopWatch2.ElapsedMilliseconds);

        Console.WriteLine(" ");
        Console.WriteLine("List Foreach loop ......");
        var stopWatch3 = Stopwatch.StartNew();
        foreach (var item in list)
        {
            Thread.Sleep(1);
        }
        stopWatch3.Stop();
        Console.WriteLine("Time take to run the foreach loop is {0} millisecond", stopWatch3.ElapsedMilliseconds);
    }

UPDATED

After @jgauffin suggestion I used @johnskeet code and found that the for loop with array is faster than following,

  • Foreach loop with array.
  • For loop with list.
  • Foreach loop with list.

See my test results and code below,

enter image description here

private static void MeasureNewTime()
    {
        var data = new double[Size];
        var rng = new Random();
        for (int i = 0; i < data.Length; i++)
        {
            data[i] = rng.NextDouble();
        }
        Console.WriteLine("Lenght of array: {0}", data.Length);
        Console.WriteLine("No. of iteration: {0}", Iterations);
        Console.WriteLine(" ");
        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 with Array: {0}", sw.ElapsedMilliseconds);

        sw = Stopwatch.StartNew();
        for (var 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 with Array: {0}", sw.ElapsedMilliseconds);
        Console.WriteLine(" ");

        var dataList = data.ToList();
        sw = Stopwatch.StartNew();
        for (int i = 0; i < Iterations; i++)
        {
            double sum = 0;
            for (int j = 0; j < dataList.Count; j++)
            {
                sum += data[j];
            }
            if (Math.Abs(sum - correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("For loop with List: {0}", sw.ElapsedMilliseconds);

        sw = Stopwatch.StartNew();
        for (int i = 0; i < Iterations; i++)
        {
            double sum = 0;
            foreach (double d in dataList)
            {
                sum += d;
            }
            if (Math.Abs(sum - correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("Foreach loop with List: {0}", sw.ElapsedMilliseconds);
    }
Diganta Kumar
  • 3,491
  • 2
  • 24
  • 29
  • 3
    This is a very poor test. a) you do too few iterations to get a conclusive answer b) That Thread.Sleep will not really wait one millisecond. Use the same method as Jon Skeet did in his answer. – jgauffin Jun 12 '14 at 05:51
  • 1
    99.99% of the time is definately spent in the thread.sleep (which makes no guarantees of how fast it will return except it won't before at least that time). Looping is very fast and sleeping is very slow, you don't use the later to test the former. – Ronan Thibaudau Apr 20 '15 at 12:02
3

Unless you're in a specific speed optimization process, I would say use whichever method produces the easiest to read and maintain code.

If an iterator is already setup, like with one of the collection classes, then the foreach is a good easy option. And if it's an integer range you're iterating, then for is probably cleaner.

GeekyMonkey
  • 10,933
  • 5
  • 30
  • 36
3

Jeffrey Richter talked the performance difference between for and foreach on a recent podcast: http://pixel8.infragistics.com/shows/everything.aspx#Episode:9317

Chuck Conway
  • 15,795
  • 10
  • 56
  • 99
2

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Oliver Friedrich
  • 8,425
  • 7
  • 38
  • 47
  • 4
    Not with an array it doesn't. Compile it and look at the IL :) (It also depends on the collection. IIRC, List uses a value type for the enumerator.) – Jon Skeet Dec 13 '08 at 20:34
  • Why would one allocation be expensive? In managed .NET, allocations are practically free aren't they, since all that is done is that the pointer is incremented in the managed heap, there is little if any fragmentation in most cases. – ApplePieIsGood Dec 13 '08 at 20:48
  • 1
    not just one allocation, also all the method-calling overhead of MoveNext() and get_Current() for each iteration. – Lucas May 19 '09 at 19:47
2

for has more simple logic to implement so it's faster than foreach.

Tarik
  • 73,061
  • 78
  • 222
  • 327
2

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.

JohannesH
  • 6,260
  • 5
  • 34
  • 67
2

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.

Craig Gidney
  • 16,378
  • 4
  • 62
  • 124
  • If the list is changing out from under you then you cannot rely on the enumerator backing a foreach loop to tell you that. It is not going to check again after it returns the value to you, resulting in a race. – hoodaticus Mar 30 '17 at 17:42
1

I mentioned this details based on speed of collection on for and foreach.

List -For Loop is slightly faster than Foreach Loop

ArrayList - For Loop is about more than 2 times faster speed than Foreach Loop.

Array - Both are in equal speed.But Foreach Loop seems to be a bit faster.

Hemalatha
  • 1
  • 1
1

I ran into a case where foreach way WAY faster than For

why foreach is faster than for loop while reading richtextbox lines

I had a case similar to the OP in that question.

A textbox reading about 72K lines, and I was accessling the Lines property(which is actually a getter method). (And apparently often in winforms there are getter methods that aren't O(1). I suppose it's O(n), so the larger the textbox the longer it takes to get a value from that 'property'. And in the for loop I had as the OP there had for(int i=0;i<textBox1.lines.length;i++) str=textBox1.Lines[i] , and it was really quite slow as it was reading the entire textbox each time it read a line plus it was reading the entire textbox each time it checked the condition.

Jon Skeet shows that you can do it accessing the Lines property just one single time(not even once per iteration, just once). Rather than twice on each iteration (which is a ton of times). Do string[] strarrlines = textBox1.Lines; and loop through the strarrlines.

But certainly a for loop in a fairly intuitive form and accessing the Lines property, is very inefficient

for (int i = 0; i < richTextBox.Lines.Length; i++)
{
    s = richTextBox.Lines[i];
}

for a textbox, or a rich textbox, it's super slow.

The OP, testing that loop on a rich textbox, found that " with 15000 lines.for loop took 8 minutes to just loop down to 15000 lines.while foreach took fraction of a second to enumerate it."

The OP at that link found this foreach to be far more efficient than his(The same OP's) for loop mentioned above. As I did.

   String s=String.Empty;
   foreach(string str in txtText.Lines)
    {
       s=str;
    }
Community
  • 1
  • 1
barlop
  • 10,225
  • 7
  • 63
  • 94
1

In my project in Windows Mobile I used a for loop for a control collection. It took 100 ms for 20 controls! A foreach loop used only 4 ms. That was a performance problem...

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
GorillaApe
  • 3,421
  • 6
  • 57
  • 100
0

At least I haven't seen any of my collegues or higher ups saying that, that's just ridiculous considering the fact that there is no significant speed difference between for and foreach. The same applies if he is asking to use it in all cases!

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Mahesh Velaga
  • 20,207
  • 5
  • 33
  • 59
0

I think for is marginally faster than foreach in most cases, but this is really missing the point. One thing I haven't seen mentioned is that, in the scenario you're talking about (i.e., a high volume web app), the difference in performance between for and foreach is going to have no bearing on the site's performance. You're going to be limited by request/response time and DB time, not for v. foreach.

That said, I don't understand your aversion to foreach. In my opinion, foreach is usually clearer in situation where either could be used. I usually reserve for for situations where I need to traverse a collection in some ugly, non-standard way.

Sean Devlin
  • 1,592
  • 11
  • 17
  • I like to be able to control things by index. In a foreach loop, you have to instead setup a variable and increment it inside the foreach if you need a counter. I guess if you don't need the index then I am fine with a foreach. – PositiveGuy Dec 23 '09 at 05:02
  • That's valid. I just find in most scenarios I want to "do something" to each element. If you need to know where you are in the collection, for is definitely the way to go. – Sean Devlin Dec 23 '09 at 05:29
0

Starting from .NET Framework 4 you can also use Parallel.For and Parallel.ForEach like described here: C# Multithreading Loop with Parallel.For or Parallel.ForEach

Jonny
  • 1
  • 1
  • 4
    Note that [link-only answers](http://meta.stackoverflow.com/tags/link-only-answers/info) are discouraged, SO answers should be the end-point of a search for a solution (vs. yet another stopover of references, which tend to get stale over time). Please consider adding a stand-alone synopsis here, keeping the link as a reference. – kleopatra Dec 18 '13 at 09:54
0

I needed to do parsing of some large data using three nested loops (on List<MyCustomType>). I thought, using Rob Fonseca-Ensor's post above, it'd be interesting to time and compare the difference using for and foreach.

The difference was: The foreach (three foreach nested like foreach{foreach{forech{}}} did the job in 171.441 seconds where as for (for{for{for{}}}) did it in 158.616 seconds.

Now 13 seconds is about 13% reduction in time to do this - which is somewhat significant to me. However, foreach is definitely far more readable than using three indexed-fors...

shadowf
  • 1,096
  • 12
  • 15
0

Ben Watson, the author of "Writing High-Performance .NET Code":

"Will these optimization matter to your program? Only if your program is CPU bound and collection iteration is a core part of your processing. As you'll see, there are ways you can hurt your performance if you're not careful, but that only matters if it was a significant part of your program to begin with. My philosophy is this: most people never need to know this, but if you do, then understanding every layer of the system is important so that you can make intelligent choices".

The most exaustive explanation can be found here: http://www.codeproject.com/Articles/844781/Digging-Into-NET-Loop-Performance-Bounds-checking

Anton Lyhin
  • 1,817
  • 2
  • 26
  • 33
0

I would suggest reading this for a specific answer. The conclusion of the article is that using for loop is generally better and faster than the foreach loop.

David Božjak
  • 14,847
  • 15
  • 63
  • 97
0
    internal static void Test()
    {
        int LOOP_LENGTH = 10000000;
        Random random = new Random((int)DateTime.Now.ToFileTime());

        {
            Dictionary<int, int> dict = new Dictionary<int, int>();
            long first_memory = GC.GetTotalMemory(true);
            var stopWatch = Stopwatch.StartNew();
            for (int i = 0; i < 64; i++)
            {
                dict.Add(i, i);
            }

            for (int i = 0; i < LOOP_LENGTH; i++)
            {
                for (int k = 0; k < dict.Count; k++)
                {
                    if (dict[k] > 1000000) Console.WriteLine("Test");
                }
            }
            stopWatch.Stop();
            var last_memory = GC.GetTotalMemory(true);
            Console.WriteLine($"Dictionary for T:{stopWatch.Elapsed.TotalSeconds}s\t M:{last_memory - first_memory}");

            GC.Collect();
        }


        {
            Dictionary<int, int> dict = new Dictionary<int, int>();
            long first_memory = GC.GetTotalMemory(true);
            var stopWatch = Stopwatch.StartNew();
            for (int i = 0; i < 64; i++)
            {
                dict.Add(i, i);
            }

            for (int i = 0; i < LOOP_LENGTH; i++)
            {
                foreach (var item in dict)
                {
                    if (item.Value > 1000000) Console.WriteLine("Test");
                }
            }
            stopWatch.Stop();
            var last_memory = GC.GetTotalMemory(true);
            Console.WriteLine($"Dictionary foreach T:{stopWatch.Elapsed.TotalSeconds}s\t M:{last_memory - first_memory}");

            GC.Collect();
        }

        {
            Dictionary<int, int> dict = new Dictionary<int, int>();
            long first_memory = GC.GetTotalMemory(true);
            var stopWatch = Stopwatch.StartNew();
            for (int i = 0; i < 64; i++)
            {
                dict.Add(i, i);
            }

            for (int i = 0; i < LOOP_LENGTH; i++)
            {
                foreach (var item in dict.Values)
                {
                    if (item > 1000000) Console.WriteLine("Test");
                }
            }
            stopWatch.Stop();
            var last_memory = GC.GetTotalMemory(true);
            Console.WriteLine($"Dictionary foreach values T:{stopWatch.Elapsed.TotalSeconds}s\t M:{last_memory - first_memory}");

            GC.Collect();
        }


        {
            List<int> dict = new List<int>();
            long first_memory = GC.GetTotalMemory(true);
            var stopWatch = Stopwatch.StartNew();
            for (int i = 0; i < 64; i++)
            {
                dict.Add(i);
            }

            for (int i = 0; i < LOOP_LENGTH; i++)
            {
                for (int k = 0; k < dict.Count; k++)
                {
                    if (dict[k] > 1000000) Console.WriteLine("Test");
                }
            }
            stopWatch.Stop();
            var last_memory = GC.GetTotalMemory(true);
            Console.WriteLine($"list for T:{stopWatch.Elapsed.TotalSeconds}s\t M:{last_memory - first_memory}");

            GC.Collect();
        }


        {
            List<int> dict = new List<int>();
            long first_memory = GC.GetTotalMemory(true);
            var stopWatch = Stopwatch.StartNew();
            for (int i = 0; i < 64; i++)
            {
                dict.Add(i);
            }

            for (int i = 0; i < LOOP_LENGTH; i++)
            {
                foreach (var item in dict)
                {
                    if (item > 1000000) Console.WriteLine("Test");
                }
            }
            stopWatch.Stop();
            var last_memory = GC.GetTotalMemory(true);
            Console.WriteLine($"list foreach T:{stopWatch.Elapsed.TotalSeconds}s\t M:{last_memory - first_memory}");

            GC.Collect();
        }
    }

Dictionary for T:10.1957728s M:2080
Dictionary foreach T:10.5900586s M:1952
Dictionary foreach values T:3.8294776s M:2088
list for T:3.7981471s M:320
list foreach T:4.4861377s M:648

mohamad tolou
  • 11
  • 1
  • 1