Monday, September 10, 2012

Loops in C#

Iteration statements in C# :
1. Do While
2.While
2.For 
4.Foreach

Above all statements keep on executing repeatedly based on given condition.Till the given condition becomes false, loop keep on executing.

More Deep into the loops :

In my experience, there are two kinds of programmers. Those who write something to get the work done and those who want to write good code. But, here we get a big question. What is good code? Good code comes from good programming practices. What are good programming practices? Actually, my aim here is not to talk about good programming practices (I’m planning to write something related to that in future!), rather to talk more about writing something which will be more effective. I'm only going to look more deeper of two loops which are commonly used nowadays, and their differences in the aspect of performance.

Difference between Do while and While :

The difference between "do while" and "While " is that a "do while" loops while the test case is true, whereas " While " loops UNTIL the test case is true (which is equivalent to looping while the test case is false).

The difference between a "do ...while" loop and a "while {} " loop is that the while loop tests its condition before execution of the contents of the loop begins; the "do" loop tests its condition after it's been executed at least once. As noted above, if the test condition is false as the while loop is entered the block of code is never executed. Since the condition is tested at the bottom of a do loop, its block of code is always executed at least once.

To further clear your concept on this, understand the syntax and description of the two loop types:
while
The while loop is used to execute a block of code as long as some condition is true. If the condition is false from the start the block of code is not executed at all. The while loop tests the condition before it's executed so sometimes the loop may never be executed if initially the condition is not met. Its syntax is as follows.


while (tested condition is satisfied)
{
block of code
}


In all constructs, curly braces should only be used if the construct is to execute more than one line of code. The above program executes only one line of code so it not really necessary (same rules apply to if...else constructs) but you can use it to make the program seem more understandable or readable.
Here is a simple example of the use of the while loop. This program counts from 1 to 100.

using system;

static void Main()
{
int count = 1;

while (count <= 100)
{
Console.WriteLine(count);
count += 1; // Notice this statement
}

}
 
Note that no semi-colons ( ; ) are to be used after the while (condition) statement. These loops are very useful because the condition is tested before execution begins. However i never seem to like these loops as they are not as clear to read as the do ...while loops. The while loop is the favorite amongst most programmers but as for me, i definitely prefer the do ...while loop.

do ....while
 
The do loop also executes a block of code as long as a condition is satisfied.

Again, The difference between a "do ...while" loop and a "while {} " loop is that the while loop tests its condition before execution of the contents of the loop begins; the "do" loop tests its condition after it's been executed at least once. As noted above, if the test condition is false as the while loop is entered the block of code is never executed. Since the condition is tested at the bottom of a do loop, its block of code is always executed at least once.
Some people don't like these loops because it is always executed at least once. When i ask them "so what?", they normally reply that the loop executes even if the data is incorrect. Basically because the loop is always executed, it will execute no matter what value or type of data is supposed to be required. The "do ....while" loops syntax is as follows
do
{
block of code
} while (condition is satisfied);

Note that a semi-colon ( ; ) must be used at the end of the do ...while loop. This semi-colon is needed because it instructs whether the while (condition) statement is the beginning of a while loop or the end of a do ...while loop. Here is an example of the use of a do loop. 


using system;
static void Main()
{
int number;
      do

Console.WriteLine("Enter a number");
 number=convert.toint32(console.ReadLine());

    while(number%2==0)
{
Console.ReadLine("Entered number is even");
}    


}

Difference between For and Foreach : 

I’m 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. 

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

*******************using foreach loop   ***************************

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’m 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’m 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’m going into the exact difference between the codes.

 FOR

cmp     dword ptr [eax+4],0           i<myInterger.Length
jle     0000000F
mov     ecx,dword ptr [eax+edx*4+8]   total += myInterger[i]
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


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
Anyone will say that both are not the same. But we will look why it differs from the for loop. The main reason for the difference is that both of them are differently understood by the compiler. The algorithm they are using is different. Two compare statements one after the other is unnecessary. It is doing the same thing again and again for no reason!
cmp                    esi,dword ptr [ebx+4]   
jl                         FFFFFFE3
cmp                    esi,dword ptr [ebx+4]
It also uses some unnecessary move statements which also may (not always, but depends) reduce the performance of the code. foreach is thinking everything as a collection and treating them as a collection. I feel, that will also reduce the performance of the work.
Therefore, I strongly feel 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. Therefore, I strongly recommend everyone to use for loop rather than foreach at any stage.

1 comment: