6

As in the topic, I learnt in school, that loop for is faster than loop while, but someone told me that while is faster.

I must optimize the program and I want to write while instead for, but I have a concern that it will be slower?

for example I can change for loop:

for (int i=0; i<x; i++)
{
   cout<<"dcfvgbh"<<endl;
}

into while loop:

i=0;
while (i<x)
{
    cout<<"dcfvgbh"<<endl;
    i++;
}
Mario Boss
  • 1,784
  • 3
  • 20
  • 43
Zosia
  • 99
  • 6
  • 3
    you could time it and find out? – user1336827 Jan 02 '14 at 22:31
  • 4
    I would be shocked if the assembly produced by both of these was not identical. – clcto Jan 02 '14 at 22:32
  • 2
    Any question that *can* be asked, *will* be asked. – Chris Dargis Jan 02 '14 at 22:32
  • I try, but program jams. – Zosia Jan 02 '14 at 22:32
  • Depends on the compiler implementation of course, but for most compilers, if you compare the assembly code this produces, i strongly suspect that you won't see a difference at all. – Guntram Blohm Jan 02 '14 at 22:32
  • 1
    check out this question: http://stackoverflow.com/questions/3629174/what-loop-is-faster-while-or-for – Connor Pearson Jan 02 '14 at 22:32
  • The two are obviously equivalent. Any reasonable compiler should generate the same code for both, which you can easily check by looking at the assembly output. – Pascal Cuoq Jan 02 '14 at 22:32
  • 4
    The first step in optimizing is to learn the name of the language you are programming in. `cout<<` is not C. – Pascal Cuoq Jan 02 '14 at 22:34
  • @clcto Well, there might be slight differences in register usage, ordering of code and jumps etc., but essentially it should be the same. – glglgl Jan 02 '14 at 22:35
  • 1
    Under *some* circumstances, [it might be possible](http://stackoverflow.com/questions/20172402/do-compilers-produce-better-code-for-do-while-loops-versus-other-types-of-loops) for a `do-while` to be faster than a `while` or `for`. But not between `while` and `for`. – Mysticial Jan 02 '14 at 22:35
  • Relevant: http://stackoverflow.com/questions/24901/is-there-a-performance-difference-between-i-and-i-in-c ;-) – Steve Jessop Jan 02 '14 at 22:39
  • while loop? When optimizing? Seriously? You obviously have to just manually implement it in assembly and inline it everywhere when you need a loop. – Purple Ice Mar 01 '19 at 10:02

5 Answers5

10

The standard requires (§6.5.3/1) that:

The for statement
for ( for-init-statement conditionopt; expressionopt) statement
is equivalent to

{
    for-init-statement
    while ( condition ) {
        statement
        expression;
    }
}

As such, you're unlikely to see much difference between them (even if execution time isn't necessarily part of the equivalence specified in the standard). There are a few exceptions listed to the equivalence as well (scopes of names, execution of the expression before evaluating the condition if you execute a continue). The latter could, at least theoretically, affect speed a little bit under some conditions, but probably not enough to notice or care about as a rule, and definitely not unless you actually used a continue inside the loop.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
7

For all intents and purposes for is just a fancy way of writing while, so there is no performance advantage either way. The main reason to use one over the other is how the intent is translated so the reader understands better what the loop is actually doing.

Gabe
  • 84,912
  • 12
  • 139
  • 238
  • 1
    Not for *all* intents and purposes, *continue* keyword has a Small but sometimes critical difference. – hyde Jan 02 '14 at 23:54
  • @hyde: Are you saying that using `continue` can be different in a `for` than a `while`? – Gabe Jan 03 '14 at 03:07
  • 1
    To convert a `for` loop which uses `continue` into a `while` loop usually requires changing the logic to not use `continue`: `for(i=0; i<10; ++i) if (i&1) continue; stuff(); if (i&2) continue; stuff2(); }` – hyde Jan 03 '14 at 10:33
  • @hyde: `continue` is just a fancy way of writing `goto`. How can it be different either way? – Gabe Jan 03 '14 at 13:43
  • A central point of your answer seems to be expressing intent when selecting *while* or *for*, so surely you see how *continue* expresses intent inside a loop. – hyde Jan 03 '14 at 15:44
  • @hyde: So are you actually just saying that use of `continue` is just one of the factors in deciding whether your intent is better expressed with `for` or `while`? If so, I agree. If you are saying that use of `continue` can have a performance impact, I disagree. – Gabe Jan 03 '14 at 17:17
  • Oh, no performance impact (or shouldn't be). I just disagree with "For *all* intents and purposes..." part: use of *continue* is the case where the two loops are different, in a way which can bite a programmer refactoring code and converting one to the other, if not aware of the difference. – hyde Jan 03 '14 at 17:52
  • By the way, depending on what you do inside the loop, for or while loop might be faster, because not all loops have same contents in them, therefore keywords like continue, goto and in general expressions, such as 2 + 2 can make them slower, check it out: `while(1) {}` is wayyyy faster than `for(int i=0;i; i++) { /* do literally anything at all, for example generate dumb comments like you can see above */}`. TL;DR while and for loop are identical. – Purple Ice Mar 01 '19 at 09:58
6

No.

Nope, it's not.

It is not faster.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
3

You cout will eat 99% of the clock cycles for this loop. Beware micro-optimization. At any rate, these two will give essentially identical code.

The only time when a for loop can be faster is when you have a known terminating condition - e.g.

for(ii = 0; ii < 24; ii++)

because some optimizing compilers will perform loop unrolling. This means they will not perform a test on every pass through the loop because they can "see" that just doing the thing inside the loop 24 times (or 6 times in blocks of 4, etc) will be a tiny bit more efficient. When the thing inside the loop is very small (e.g. jj += ii;), such optimization makes the for loop a bit faster than the while (which typically doesn't do "unrolling").

Otherwise - no difference.

update at the request of @zeroth

Source: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.47.9346&rep=rep1&type=pdf

Quote from source (my emphasis):

Unrolling a loop at the source- code level involves identification of loop constructs (e.g., for, while, do-while, etc.), determination of the loop count to ensure that it is a counting loop, replication of the loop body and the adjustment of loop count of the unrolled loop. A prologue or epilogue code may also be inserted. Using this approach, it is difficult to unroll loops formed using a while and goto statements since the loop count is not obvious. However, for all but the simplest of loops, this approach is tedious and error prone.

The other alternative is to unroll loops automatically. Automatic unrolling can be done early on source code, late on the unoptimized intermediate representation, or very late on an optimized representation of the program. If it is done at the source-code level, then typically only counting loops formed using for statements are unrolled. Unrolling loops formed using other control constructs is difficult since the loop count is not obvious.

Community
  • 1
  • 1
Floris
  • 45,857
  • 6
  • 70
  • 122
  • This is very interesting, but I'd like to know more about why while loops are not unrolled when a for loop would be, or which compilers. – Brandon Jan 02 '14 at 23:34
1

To the best of my knowledge swapping out for loops for while loops is not an established optimization technique.

Both your examples will be identical in performance, but as an exercise you could time them to confirm this for yourself.

Richard Viney
  • 957
  • 16
  • 31