FOREACH Vs. FOR in C#

Using the code

I am going to take a very small piece of code for two popular looping statements for and foreach. We will look some code and will see what it does, more in detail about the functionality.

FOR

int[] myInterger = new int[1];
int total = 0;
for(int i = 0; i < myInterger.Length; i++)
{
total += myInterger;
}

foreach

int[] myInterger = new int[1];
int total = 0;
foreach(int i in myInterger)
{
total += i;
}

Both codes will produce the same result. foreach is used on top of collections to traverse through while for can be used on anything for the same purpose. I am not going to explain whatsoever about the code. Before going in more deeper, I think all of you are familiar with ILDasm which is used to generate IL code, and CorDbg tool which is normally used to generate JIT compiled code.

The IL code produced by C# compiler is optimized up to certain extend, while leaving some part to JIT. Anyway, this is not really what matters to us. So, when we talk about the optimization, two things we must consider. First is C# compiler and the second is JIT.

So, rather than looking more deep into IL code, we will see more about the code which is emitted by JIT. That is the code which will run on our machine. I am now using AMD Athlon 1900+. The code highly depends on our hardware. Therefore, what you may get from your machine may differ from mine up to a certain extend. Anyway, the algorithms wont change that much.

In variable declaration, foreach has five variable declarations (three Int32 integers and two arrays of Int32) while for has only three (two Int32 integers and one Int32 array). When it goes to loop through, foreach copies the current array to a new one for the operation. While for doesn’t care of that part.

Here, I am going into the exact difference between the codes.

FOR

Instruction                           Effect

cmp     dword ptr [eax+4],0           i<myInterger.Length
jle     0000000F
mov     ecx,dword ptr [eax+edx*4+8]   total += myInterger
inc     edx                           ++i
cmp     esi,dword ptr [eax+4]         i<myInterger.Length
jl      FFFFFFF8

I ll explain what is happening here. The esi register which holds the value of i and the length of myInteger array are compared at two stages. The first one is done only once to check the condition and if the loop can continue, the value is added. For the loop, it is done at the second stage. Inside the loop, it is well optimized and as explained, the work is done with perfect optimization.
foreach

Instruction                            Effect

cmp     esi,dword ptr [ebx+4]          i<myInterger.Length
jl      FFFFFFE3
cmp     esi,dword ptr [ebx+4]          i<myInterger.Length
jb      00000009
mov     eax,dword ptr [ebx+esi*4+8]
mov     dword ptr [ebp-0Ch],eax
mov     eax,dword ptr [ebp-0Ch]
add     dword ptr [ebp-8],eax          total += i
inc     esi                            ++i
cmp     esi,dword ptr [ebx+4]          i<myInterger.Length
jl      FFFFFFE3

For loop is best than for each loop in performance point of view

admin

Back to top