none
While loop VS For loop

    Question

  • I was told today that a for loop is more efficient that a while loop. Is this true? I have never herd this before. We are talking about the C# language also, so I dont know if this would be different across languages like java, C++, actionscript, etc...
    Friday, March 12, 2010 5:50 PM

Answers

  • A for loop can be more efficient, especially if it's being used in in a way that the JIT can eliminate array bounds checking.  

    However, I wouldn't use this as a determining factor between choosing between a for loop and a while loop.  It's much better to use the construct that follows the way you think about the algorithm - rather than focusing on micro-efficiencies.  If, and only if, you find a measured performance problem in your code, then think about optimizations.

    Reed Copsey, Jr. - http://reedcopsey.com
    • Proposed as answer by DiegoCattaruzzaMVP Saturday, March 13, 2010 10:51 AM
    • Marked as answer by SamAgain Monday, March 22, 2010 3:10 AM
    • Marked as answer by SamAgain Monday, March 22, 2010 3:10 AM
    Friday, March 12, 2010 6:52 PM
    Moderator

All replies

  • In the IL they generate they are nearly identical.  Create one of each and use idlasm to inspect the output, you will see the code is identical.  You can also run an iteration test, create a while and for going in the same direction and time them both, the results should be nearly identical as well. 


    Chris Dupuy techblog.chrisdupuy.com
    • Proposed as answer by exuviae Friday, March 12, 2010 8:46 PM
    Friday, March 12, 2010 6:06 PM
  • A for loop can be more efficient, especially if it's being used in in a way that the JIT can eliminate array bounds checking.  

    However, I wouldn't use this as a determining factor between choosing between a for loop and a while loop.  It's much better to use the construct that follows the way you think about the algorithm - rather than focusing on micro-efficiencies.  If, and only if, you find a measured performance problem in your code, then think about optimizations.

    Reed Copsey, Jr. - http://reedcopsey.com
    • Proposed as answer by DiegoCattaruzzaMVP Saturday, March 13, 2010 10:51 AM
    • Marked as answer by SamAgain Monday, March 22, 2010 3:10 AM
    • Marked as answer by SamAgain Monday, March 22, 2010 3:10 AM
    Friday, March 12, 2010 6:52 PM
    Moderator
  • The two are very different.  They each loop until a variable that is checked against a specified value passes or fails the test condition.  The difference lies in how this 'condition' variable is modified, or allowed to be modified.

    The for loop modifies the variable itself.  It defines the number of iterations through the loop, and exits when the setpoint is reached. 

    The while loop has no direct control over its' condition variable.  That control must be implemented by you, the developer.  The number of iterations is not fixed.  Basically, it stops code execution from moving forward until the condition is met.  It does this by putting the CPU into a loop to repeat the same code over and over.  The count is irrelevant, because the purpose is to not move forward until the condition is met. This consumes the CPU until it exits.


    Mark the best replies as answers. "Fooling computers since 1971."
    Friday, March 12, 2010 6:57 PM
  • The for loop modifies the variable itself.  It defines the number of iterations through the loop, and exits when the setpoint is reached. 
    Sorry Rudy, but I have to argue semantics with this description (because I'm a stickler for semantics).

    The difference between for and while is that the for construct provides three sections:

    for (initialization; loop test; post-body expression)
    {
    }

    The while loop only provides one:

    while (loop test)
    {
    }

    The loop does not "modify the variable itself". There is the initialization code you provide (one or more variables), an expression that is evaluated before the loop body to test if the loop body should execute, and finally the post-body expression which is simply an expression that is evaluated each time the loop body is executed (after the body). Note that there is nothing about magically modified variables in this description. It is up to you to modify variables. Whether you do that in the body, the post-body expression, or don't do it at all is up to you.

    The following is perfectly legit:

    for (int j = length, k = 1; j > 0; output(k++))
    {
        if (condition(j))
            // do something
        else
            j--;
    }

    None of the three sections are required. This is also perfectly legit:

    for (;;)
    {
    }

    Or even:

    for (; j < k;)
    {
    }

    Which of course makes for and while perfectly identical.


    As for the original question, you should always write code that is first correct, second readable, and finally efficient (in that order).
    Friday, March 12, 2010 7:34 PM
  • Okey Dokey, I am just too used to teaching this heady stuff to kids.  Volunteer stuff.
    Mark the best replies as answers. "Fooling computers since 1971."
    Friday, March 12, 2010 8:07 PM
  • A for loop can be more efficient when implemented in machine language, but you really don't want to try to micro manage high level langagues today.  Some GPU implementations of common algorithms can achieve processing gains approaching 1000 times over single threaded CPU implementations.  There is nothing like thought to optimize a program. 
    Friday, March 12, 2010 8:40 PM
  • They are sometimes the same thing :-)

    Trivial Example but:

                Int32 j = 0;
    
                for (Int32 i = 0; i < 100; i++ )
                {
                    j += i;
                }
    
                Int32 k = 0;
                while(k < 100)
                {
                    j += k;
                    k++;
                }
    

    reflects back into:

            int j = 0;
            for (int i = 0; i < 100; i++)
            {
                j += i;
            }
            for (int k = 0; k < 100; k++)
            {
                j += k;
            }
    


    jon.stromer.galley
    Friday, March 12, 2010 9:17 PM
  • Okey Dokey, I am just too used to teaching this heady stuff to kids.  Volunteer stuff.
    Mark the best replies as answers. "Fooling computers since 1971."

    Allow me to extend a second apology. I know I can be a PITA sometimes.
    Friday, March 12, 2010 9:36 PM
  • Don't know why it would be.  Consider the following two methods of accomplishing the same result.
    for (int i=0; i < 10; i++)
    {
          this.DoSomething();
    }
    
    int i=0;
    
    while (i < 10)
    {
         this.DoSomething();
         i++;
    }
    If you coded this and ran each through it in the debugger counting steps, you'd find that they are the same number of steps.

    The choice of using while versus for is, for me, semantic and functional.

    A for loop is iterative and based on an index that increments at a steady rate.  Note that this is not a limitation on for, as the initializer, conditional, and incremental can be any legitimate expression.  I could create some crazy for loop if I wanted like the following:

    for (int i=0; q < 12; i = this.TransformQ(ref q))

    ...but it violates the accepted semantic of the for loop, which is a simple, iterative loop of finite known length.

    A while loop, on the other hand, is used when the for semantic wouldn't be appropriate (such as a conditional where two or more values require checking).
    Friday, March 12, 2010 10:22 PM

  • If you coded this and ran each through it in the debugger counting steps, you'd find that they are the same number of steps.

    But that doesn't always equate to the same performance.

    The major difference, however, comes from optimizations that can happen in the JIT compiler, depending on what you're doing.

    Take the following:

    double[] doubleArray = new double[100];
    
    int i=0;
    while (i<doubleArray.Length)
    {
       // Do something which uses doubleArray[i]
       ++i;
    }
    
    
    // vs:
    
    for (int i=0;i<doubleArray.Length;++i)
    {
        // Do something using doubleArray[i]
    }
    In the second case, as long as you always are referring to doubleArray[i], the JIT actually optimizes this dramatically, removing the arrays bounds checking at runtime.  This can cause the second case to run a LOT faster, even though the theoretical "number of instructions" is identical.

    That being said, I still wouldn't choose perf. as my measure for this - I'd go for readability and understandability in terms of what the algorithm is trying to do...

    Reed Copsey, Jr. - http://reedcopsey.com
    Saturday, March 13, 2010 12:17 AM
    Moderator
  • I could create some crazy for loop if I wanted like the following:

    for (int i=0; q < 12; i = this.TransformQ(ref q))

    ...but it violates the accepted semantic of the for loop, which is a simple, iterative loop of finite known length.
    Says who?

    for (Node node = Head; node != null; node = node.Next)
    {
    }

    Does that violate your accepted semantic of the for loop? I'm not incrementing an index.

    What about the RemoveAt case?

    for (int n = 0; n < array.Count; )
    {
        if (conditon(array[n]))
            array.RemoveAt(n);
        else
            n++;
    }

    Does that violate your accepted semantic of the for loop? The increment is conditional.
    Saturday, March 13, 2010 2:18 PM
  • Says me, oh, defiant and angry one.  The reason?  Readability and the presumption of intent of other sets of eyes.  To answer your questions, Yes, it does and no but you're doing it wrong.  The accepted semantic for a for loop is exactly what I said.  Simple, iterative, with constant increment or decrement.

    The first example you provided contravenes the commonly accepted semantic and would be better served semantically by the while loop.

    Node node = head;
    
    while (node != null)
    {
        // do something with node
        node = node.Next;
    }
    

    This is a typical linked list iteration using a while.  You want to use a for?  By all means go ahead.

    The second is a common for application, but is accomplished better as follows.  Granted, it iterates from greatest to least, but the end result is the same and it is clear from the for what the coder is attempting.

    for (int n = array.Count - 1; n >= 0; n--;)
    {
        if (conditon(array[n]))
        {
            array.RemoveAt(n);
        }
    }

    Believe it or not, there are accepted semantics for when it is appropriate to perform certain constructs and when it is not.  Whether you choose to use them or not is up to you clearly, but when the code you write might have to be supported by someone else, you not only want the code to work, but you also want others who might have to support your code to be able to understand quickly what you are attempting (preferably without having to write a novella's worth of comments).  It also helps to stick to common semantics for constructs for your own benefit in the case you leave the code for months, or maybe years at a time and have to support it yourself.

    In the cases above, you took simple tasks with accepted patterns and made them needlessly "cute".  Why?  To prove that you can?  Of course you can, that's not in question.  Whether you should is the question.  But no one's going to make that decision for you, so if you feel all bristly because I suggested using an accepted semantic rather than indulging your creative side in the most trivial of pursuits, well, I apologize profusely for offending your sensibilities.

    Thursday, April 01, 2010 7:57 PM