Coding for Performance : for vs. foreach

Use the MeasureIt program described in Chapter 1 to see for yourself the difference in iterating collections using for loops or foreach. Using standard for loops is significantly faster in all the cases. However, if you do your own simple test, you might notice equivalent performance depending on the scenario. In many cases, .NET will actually convert simple foreach statements into standard for loops.

Take a look at the ForEachVsFor sample project, which has this code:

int[] arr = new int[100];

for (int i = 0; i < arr.Length; i++)


arr[i] = i;


int sum = 0;

foreach (int val in arr)


sum += val;


sum = 0;

IEnumerable<int> arrEnum = arr;

foreach (int val in arrEnum)


sum += val;


Once you build this, then decompile it using an IL reflection tool. You will see that the first foreach is actually compiled as a for loop. The IL looks like this:

// loop start (head: IL_0034)

IL_0024: ldloc.s CS$6$0000

IL_0026: ldloc.s CS$7$0001

IL_0028: ldelem.i4

IL_0029: stloc.3

IL_002a: ldloc.2

IL_002b: ldloc.3

IL_002c: add

IL_002d: stloc.2

IL_002e: ldloc.s CS$7$0001

IL_0030: ldc.i4.1 IL_0031: add

IL_0032: stloc.s CS$7$0001

IL_0034: ldloc.s CS$7$0001

IL_0036: ldloc.s CS$6$0000

IL_0038: ldlen

IL_0039: conv.i4

IL_003a: blt.s IL_0024

// end loop

There are a lot of stores, loads, adds, and a branch—it is all quite simple. However, once we cast the array to an IEnumerable<int> and do the same thing, it gets a lot more expensive:

IL_0043: callvirt instance class

[mscorlib]System.Collections.Generic.IEnumerator`1&amp;lt;!0&amp;gt; class [mscorlib]System.Collections.Generic.IEnumerable`1&amp;lt;int32&amp;gt;::GetEnumerator()

IL_0048: stloc.s CS$5$0002



IL_004a: br.s


// loop start (head: IL_005a)

IL_004c: ldloc.s CS$5$0002

IL_004e: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1&amp;lt;int32&amp;gt;::get_Current()

IL_0053: stloc.s val

IL_0055: ldloc.2

IL_0056: ldloc.s val

IL_0058: add

IL_0059: stloc.2

IL_005a: ldloc.s CS$5$0002

IL_005c: callvirt instance bool


IL_0061: brtrue.s IL_004c

// end loop

IL_0063: leave.s IL_0071

} // end .try



IL_0065: ldloc.s CS$5$0002

IL_0067: brfalse.s IL_0070

IL_0069: ldloc.s CS$5$0002

IL_006b: callvirt instance void [mscorlib]System.IDisposable::Dispose()

IL_0070: endfinally

} // end handler

We have 4 virtual method calls, a try-finally, and, not shown here, a memory allocation for the local enumerator variable which tracks the enumeration state. That is much more expensive than the simple for loop. It uses more CPU and more memory!

Remember, the underlying data structure is still an array—a for loop is possible—but we are obfuscating that by casting to an IEnumerable. The important lesson here is the one that was mentioned at the top of the chapter: In-depth performance optimization will often defy code abstractions. foreach is an abstraction of a loop, and IEnumerable is an abstraction of a collection. Combined, they dictate behavior that defies the simple optimizations of a for loop over an array.

Source :  : Writing High-Performance .NET Code

For all your application development needs, visit for a fiscally conscious proposal that meets your needs ( So I can keep this blog going as well!!!!)

Alternatively click through the link   if you found this article interesting. (This will help the companies Search engine rankings)



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Website Powered by

Up ↑

%d bloggers like this: