Performance Difference for Control Structures 'For' and 'Foreach' in C#

Performance difference for control structures 'for' and 'foreach' in C#

Well, it partly depends on the exact type of list. It will also depend on the exact CLR you're using.

Whether it's in any way significant or not will depend on whether you're doing any real work in the loop. In almost all cases, the difference to performance won't be significant, but the difference to readability favours the foreach loop.

I'd personally use LINQ to avoid the "if" too:

foreach (var item in list.Where(condition))
{
}

EDIT: For those of you who are claiming that iterating over a List<T> with foreach produces the same code as the for loop, here's evidence that it doesn't:

static void IterateOverList(List<object> list)
{
foreach (object o in list)
{
Console.WriteLine(o);
}
}

Produces IL of:

.method private hidebysig static void  IterateOverList(class [mscorlib]System.Collections.Generic.List`1<object> list) cil managed
{
// Code size 49 (0x31)
.maxstack 1
.locals init (object V_0,
valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<object> V_1)
IL_0000: ldarg.0
IL_0001: callvirt instance valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<!0> class [mscorlib]System.Collections.Generic.List`1<object>::GetEnumerator()
IL_0006: stloc.1
.try
{
IL_0007: br.s IL_0017
IL_0009: ldloca.s V_1
IL_000b: call instance !0 valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<object>::get_Current()
IL_0010: stloc.0
IL_0011: ldloc.0
IL_0012: call void [mscorlib]System.Console::WriteLine(object)
IL_0017: ldloca.s V_1
IL_0019: call instance bool valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<object>::MoveNext()
IL_001e: brtrue.s IL_0009
IL_0020: leave.s IL_0030
} // end .try
finally
{
IL_0022: ldloca.s V_1
IL_0024: constrained. valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<object>
IL_002a: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_002f: endfinally
} // end handler
IL_0030: ret
} // end of method Test::IterateOverList

The compiler treats arrays differently, converting a foreach loop basically to a for loop, but not List<T>. Here's the equivalent code for an array:

static void IterateOverArray(object[] array)
{
foreach (object o in array)
{
Console.WriteLine(o);
}
}

// Compiles into...

.method private hidebysig static void IterateOverArray(object[] 'array') cil managed
{
// Code size 27 (0x1b)
.maxstack 2
.locals init (object V_0,
object[] V_1,
int32 V_2)
IL_0000: ldarg.0
IL_0001: stloc.1
IL_0002: ldc.i4.0
IL_0003: stloc.2
IL_0004: br.s IL_0014
IL_0006: ldloc.1
IL_0007: ldloc.2
IL_0008: ldelem.ref
IL_0009: stloc.0
IL_000a: ldloc.0
IL_000b: call void [mscorlib]System.Console::WriteLine(object)
IL_0010: ldloc.2
IL_0011: ldc.i4.1
IL_0012: add
IL_0013: stloc.2
IL_0014: ldloc.2
IL_0015: ldloc.1
IL_0016: ldlen
IL_0017: conv.i4
IL_0018: blt.s IL_0006
IL_001a: ret
} // end of method Test::IterateOverArray

Interestingly, I can't find this documented in the C# 3 spec anywhere...

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

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

Difference between foreach and for loops over an IEnumerable class in C#

foreach creates an instance of an enumerator (returned from GetEnumerator) and that enumerator also keeps state throughout the course of the foreach loop. It then repeatedly calls for the Next() object on the enumerator and runs your code for each object it returns.

They don't boil down to the same code in any way, really, which you'd see if you wrote your own enumerator.

Performance analyze for loop and foreach

My decision would not be based on some simple performance loop like this. I am assuming that you have a frequent use of loops/large data sets. You will not notice the difference until we start talking about iterations in the hundreds of thousands (at a minimum).

1) If you are writing applications with potential memory pressured frameworks (XBOX, Windows Phone, Silverlight). I would use the for loop as foreach can leave lightweight "garbage" that can be left behind for collectioning. When I was doing XBOX development years ago for games, a common trick was to initialize a fixed array of items shown on a screen using a for loop and keep that in memory and then you don't have to worry about garbage collection/memory adjustments/garbage collection etc. This can be an issue if you have a loop like this called 60+ times/second (i.e. games)

2) If you have a very large set you are iterating AND performance is your key decision driver (remember these numbers are not going to be noticeable unless they are large), then you may want to look at parallelizing your code. The difference then might not be for vs foreach, but Parallel.For vs Parallel.Foreach vs PLINQ (AsParallel() method). You have have different threads tackle the problem.

Edit: In a production application, you are more than likely going to have some kind of logic in your loops which will take >>> time to iterate an item. Once you add that to the mix performance drivers usually shift to the actual logic not optimizing iterations (which the compiler does pretty well).

A faster loop approach ('for' and 'foreach')?

You can always benchmark them. Use a Stopwatch and iterate over, say, ten million iterations to see which goes faster.

What I think you'll find, though, is that the two are nearly identical since the JIT compiler optimizes foreach on an array to basically a for.

flevine100 is actually right that in general a for is slightly more efficient than a foreach for types whose GetEnumerator methods create a new object implementing IEnumerator or IEnumerator<T> (due to the memory allocation and method call overhead); this is less the case for most of the collections in System.Collections.Generic, however, due to their explicit IEnumerable implementation using value type enumerators (not to mention that the foreach construct does not actually require an IEnumerable implementation in the first place).

It's even less the case for arrays specifically because they are fixed-size and therefore trivial to optimize by the JIT compiler.

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

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

Are foreach and the use of collections slow?

Short answer:

Code that is hard to read eventually results in software that behaves and performs poorly.

Long answer:

There was a culture of micro-optimization suggestions in early .NET. Partly it was because a few Microsoft's internal tools (such as FxCop) had gained popularity among general public. Partly it was because C# had and has aspirations to be a successor to assembly, C, and C++ regarding the unhindered access to raw hardware performance in the few hottest code paths of a performance critical application. This does require more knowledge and discipline than a typical application, of course. The consequences of performance related decisions in framework code and in app code are also quite different.

The net impact of this on C# coding culture has been positive, of course; but it would be ridiculous to stop using foreach or is or "" just in order to save a couple CIL instructions that your recent jitter could probably optimize away completely if it wanted to.

There are probably very many loops in your app and probably at most one of them might be a current performance bottleneck. "Optimizing" a non-bottleck for perfomance at the expense of readability is a very bad deal.

Major difference between 'for each' and 'for' loop in .NET

See The Code Project article foreach vs. for (C#)*.

foreach is thinking about everything as a collection and is treating them as a collection. That will also reduce the performance of the work.

To write high performance code that is not for collections, use a for loop.

Even for collections, foreach may look handy when using, but it's not that efficient. Therefore, I strongly recommend everyone to use a for loop rather than foreach at any stage.

Performance of foreach vs. Where().Select()

Linq is not designed to improve performance. It is designed to improve coding efficiency. It can, in some cases, be more performant than bad loops (e.g. when you are looking for the existence of an item, Any will stop when an item is found, but a bad loop may continue looping), but in general it will not improve performance.

So use whatever you understand better (IMHO the where delegate you use is much harder to understand) and use Linq to improve readability.

If you have identified a performance problem, then get a good profiler to determine where the most time is being spend. I'd be surprised if the Linq methods are actually a bottleneck.

That said, you could also structure the query this way:

var reslutList = KeysCollection.Where(key => SomeCondition(key))
.Where(key => AnotherCondition(CreateAnotherKey(key)))
.Select(key => new MyItemWrapper { Id = key })
.ToList();

Which might be easier to understand than either the loop or the custom delegate.



Related Topics



Leave a reply



Submit