48

You can get the same output with for and while loops:

While:

$i = 0;
while ($i <= 10){
  print $i."\n";
  $i++;
};

For:

for ($i = 0; $i <= 10; $i++){
  print $i."\n";
}

But which one is faster?

Mark Lalor
  • 7,820
  • 18
  • 67
  • 106
  • 9
    Measure them if you want (but they're probably equal). – Michael Foukarakis Sep 02 '10 at 16:34
  • 4
    Bet you they generate exactly the same byte code. – zwol Sep 02 '10 at 16:35
  • 8
    `for` in most languages is syntactic sugar for an equivalent `while` loop, which is in turn syntactic sugar for a set of labels and `gotos` down in assembly or IL. Given an efficient implementation of the language spec, these will be roughly equal. Some languages include internal "comments" giving hints to decompilers/reflectors about what the original code looked like, which will have a negligible effect on performance. I think you'll find that the biggest execution time differences between these are inherent in OS scheduling. – KeithS Sep 02 '10 at 16:51
  • 12
    You are probably better off not knowing. If you use the knowledge of a possible premature optimization to influence your programming, choosing slightly faster code over the most readable design before even finding out if you need the speed, you fail. – Bill K Sep 02 '10 at 17:27
  • In C: you can also compare their asm output: `gcc -S mycsource.c` – Yousha Aleayoub Mar 28 '18 at 13:21
  • It shouldn't matter which is faster. If it does matter then benchmark it using your real code and see for yourself. The answers to this other question might be useful as well: https://stackoverflow.com/questions/3586633 – David Sep 02 '10 at 16:37

16 Answers16

30

That clearly depends on the particular implementation of the interpreter/compiler of the specific language.

That said, theoretically, any sane implementation is likely to be able to implement one in terms of the other if it was faster so the difference should be negligible at most.

Of course, I assumed while and for behave as they do in C and similar languages. You could create a language with completely different semantics for while and for

Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
14

I find the fastest loop is a reverse while loop, e.g:

var i = myArray.length;
while(i--){
  // Do something
}
Linga
  • 10,379
  • 10
  • 52
  • 104
Anthony
  • 141
  • 2
14

In C#, the For loop is slightly faster.

For loop average about 2.95 to 3.02 ms.

The While loop averaged about 3.05 to 3.37 ms.

Quick little console app to prove:

 class Program
    {
        static void Main(string[] args)
        {
            int max = 1000000000;
            Stopwatch stopWatch = new Stopwatch();

            if (args.Length == 1 && args[0].ToString() == "While")
            {
                Console.WriteLine("While Loop: ");
                stopWatch.Start();
                WhileLoop(max);
                stopWatch.Stop();
                DisplayElapsedTime(stopWatch.Elapsed);
            }
            else
            {
                Console.WriteLine("For Loop: ");
                stopWatch.Start();
                ForLoop(max);
                stopWatch.Stop();
                DisplayElapsedTime(stopWatch.Elapsed);
            }
        }

        private static void WhileLoop(int max)
        {
            int i = 0;
            while (i <= max)
            {
                //Console.WriteLine(i);
                i++;
            };
        }

        private static void ForLoop(int max)
        {
            for (int i = 0; i <= max; i++)
            {
                //Console.WriteLine(i);
            }
        }

        private static void DisplayElapsedTime(TimeSpan ts)
        {
            // Format and display the TimeSpan value.
            string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                ts.Hours, ts.Minutes, ts.Seconds,
                ts.Milliseconds / 10);
            Console.WriteLine(elapsedTime, "RunTime");
        }
    }
Jéf Bueno
  • 425
  • 1
  • 5
  • 23
Shane
  • 4,185
  • 8
  • 47
  • 64
  • 1
    It can be possible that when compiler was running while loop it ran some other background task also bcz of that it took slightly longer. How did you make sure of those things?? – Narendra Jaggi May 12 '15 at 18:13
  • I didn't. This wasn't some clean room experiment. I did run this same process many times and consistently would be similar results. So that would tell me the likelihood of some background task randomly affecting the times only for the While Loop was minimal. – Shane May 13 '15 at 18:35
  • 2
    Which is faster depends on what you're iterating over. [Here's a blog comparison that benchmarks iterations](http://cc.davelozinski.com/c-sharp/for-vs-foreach-vs-while) over multiple kinds of objects, such as DataRows and custom objects, also including the performance of the While loop construct and not just the for and foreach constructs. – Free Coder 24 May 20 '16 at 06:27
  • Old thread, but this also depends on things like initialization time. When doing performance tests, you MUST include a heatup period, and to iterate the A/B testing multiple times... so you can exclude which test was ran first, and the overhead of the `StopWatch` start and stop. – Stmated Apr 13 '22 at 11:21
5

As others have said, any compiler worth its salt will generate practically identical code. Any difference in performance is negligible - you are micro-optimizing.

The real question is, what is more readable? And that's the for loop (at least IMHO).

Aillyn
  • 23,354
  • 24
  • 59
  • 84
5

As for infinite loops for(;;) loop is better than while(1) since while evaluates every time the condition but again it depends on the compiler.

Ilian Zapryanov
  • 1,132
  • 2
  • 16
  • 28
3

I used a for and while loop on a solid test machine (no non-standard 3rd party background processes running). I ran a for loop vs while loop as it relates to changing the style property of 10,000 <button> nodes.

The test is was run consecutively 10 times, with 1 run timed out for 1500 milliseconds before execution:

Here is the very simple javascript I made for this purpose

function runPerfTest() {
    "use strict";

    function perfTest(fn, ns) {
        console.time(ns);
        fn();
        console.timeEnd(ns);
    }

    var target = document.getElementsByTagName('button');

    function whileDisplayNone() {
        var x = 0;
        while (target.length > x) {
            target[x].style.display = 'none';
            x++;
        }
    }

    function forLoopDisplayNone() {
        for (var i = 0; i < target.length; i++) {
            target[i].style.display = 'none';
        }
    }

    function reset() {
        for (var i = 0; i < target.length; i++) {
            target[i].style.display = 'inline-block';
        }
    }

    perfTest(function() {
        whileDisplayNone();
    }, 'whileDisplayNone');

    reset();

    perfTest(function() {
        forLoopDisplayNone();
    }, 'forLoopDisplayNone');

    reset();
};

$(function(){
    runPerfTest();
    runPerfTest();
    runPerfTest();
    runPerfTest();
    runPerfTest();
    runPerfTest();
    runPerfTest();
    runPerfTest();
    runPerfTest();
    setTimeout(function(){
        console.log('cool run');
        runPerfTest();
    }, 1500);
});

Here are the results I got

pen.js:8 whileDisplayNone: 36.987ms
pen.js:8 forLoopDisplayNone: 20.825ms

pen.js:8 whileDisplayNone: 19.072ms
pen.js:8 forLoopDisplayNone: 25.701ms

pen.js:8 whileDisplayNone: 21.534ms
pen.js:8 forLoopDisplayNone: 22.570ms

pen.js:8 whileDisplayNone: 16.339ms
pen.js:8 forLoopDisplayNone: 21.083ms

pen.js:8 whileDisplayNone: 16.971ms
pen.js:8 forLoopDisplayNone: 16.394ms

pen.js:8 whileDisplayNone: 15.734ms
pen.js:8 forLoopDisplayNone: 21.363ms

pen.js:8 whileDisplayNone: 18.682ms
pen.js:8 forLoopDisplayNone: 18.206ms

pen.js:8 whileDisplayNone: 19.371ms
pen.js:8 forLoopDisplayNone: 17.401ms

pen.js:8 whileDisplayNone: 26.123ms
pen.js:8 forLoopDisplayNone: 19.004ms

pen.js:61 cool run
pen.js:8 whileDisplayNone: 20.315ms
pen.js:8 forLoopDisplayNone: 17.462ms

Here is the demo link

Update

A separate test I have conducted is located below, which implements 2 differently written factorial algorithms, 1 using a for loop, the other using a while loop.

Here is the code:

function runPerfTest() {
    "use strict";

    function perfTest(fn, ns) {
        console.time(ns);
        fn();
        console.timeEnd(ns);
    }

    function whileFactorial(num) {
        if (num < 0) {
            return -1;
        }
        else if (num === 0) {
            return 1;
        }
        var factl = num;
        while (num-- > 2) {
            factl *= num;
        }
        return factl;
    }

    function forFactorial(num) {
        var factl = 1;
        for (var cur = 1; cur <= num; cur++) {
            factl *= cur;
        }
        return factl;
    }

    perfTest(function(){
        console.log('Result (100000):'+forFactorial(80));
    }, 'forFactorial100');

    perfTest(function(){
        console.log('Result (100000):'+whileFactorial(80));
    }, 'whileFactorial100');
};

(function(){
    runPerfTest();
    runPerfTest();
    runPerfTest();
    runPerfTest();
    runPerfTest();
    runPerfTest();
    runPerfTest();
    runPerfTest();
    runPerfTest();
    console.log('cold run @1500ms timeout:');
    setTimeout(runPerfTest, 1500);
})();

And the results for the factorial benchmark:

pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.280ms
pen.js:38 Result (100000):7.156945704626378e+118
pen.js:8 forFactorial100: 0.241ms
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.254ms
pen.js:38 Result (100000):7.156945704626378e+118
pen.js:8 forFactorial100: 0.254ms
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.285ms
pen.js:38 Result (100000):7.156945704626378e+118
pen.js:8 forFactorial100: 0.294ms
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.181ms
pen.js:38 Result (100000):7.156945704626378e+118
pen.js:8 forFactorial100: 0.172ms
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.195ms
pen.js:38 Result (100000):7.156945704626378e+118
pen.js:8 forFactorial100: 0.279ms
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.185ms
pen.js:55 cold run @1500ms timeout:
pen.js:38 Result (100000):7.156945704626378e+118
pen.js:8 forFactorial100: 0.404ms
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.314ms

Conclusion: No matter the sample size or specific task type tested, there is no clear winner in terms of performance between a while and for loop. Testing done on a MacAir with OS X Mavericks on Chrome evergreen.

AlphaG33k
  • 1,588
  • 1
  • 12
  • 24
3

If that were a C program, I would say neither. The compiler will output exactly the same code. Since it's not, I say measure it. Really though, it's not about which loop construct is faster, since that's a miniscule amount of time savings. It's about which loop construct is easier to maintain. In the case you showed, a for loop is more appropriate because it's what other programmers (including future you, hopefully) will expect to see there.

nmichaels
  • 49,466
  • 12
  • 107
  • 135
2

Set the loop iterations to 10,000.

Find the time in milliseconds>Run Loop>find time in milliseconds and subtract the first timer.

Do it for both codes, what ever one has the lowest milliseconds it runs faster. You might want to run the test multiple times and average them out to reduce the likelihood of background processes influencing the test.

You are likely to get really similar times on both of them, but I am interested to see if one is always just slightly faster.

AttackingHobo
  • 259
  • 3
  • 12
1

Some optimizing compilers will be able to do better loop unrolling with a for loop, but odds are that if you're doing something that can be unrolled, a compiler smart enough to unroll it is probably also smart enough to interpret the loop condition of your while loop as something it can unroll as well.

Chris
  • 1,303
  • 8
  • 6
1

I also tried to benchmark the different kinds of loop in C#. I used the same code as Shane, but I also tried with a do-while and found it to be the fastest. This is the code:

using System;
using System.Diagnostics;


public class Program
{
    public static void Main()
    {
        int max = 9999999;
        Stopwatch stopWatch = new Stopwatch();

        Console.WriteLine("Do While Loop: ");
        stopWatch.Start();
        DoWhileLoop(max);
        stopWatch.Stop();
        DisplayElapsedTime(stopWatch.Elapsed);
        Console.WriteLine("");
        Console.WriteLine("");

        Console.WriteLine("While Loop: ");
        stopWatch.Start();
        WhileLoop(max);
        stopWatch.Stop();
        DisplayElapsedTime(stopWatch.Elapsed);
        Console.WriteLine("");
        Console.WriteLine("");

        Console.WriteLine("For Loop: ");
        stopWatch.Start();
        ForLoop(max);
        stopWatch.Stop();
        DisplayElapsedTime(stopWatch.Elapsed);
    }

    private static void DoWhileLoop(int max)
    {
        int i = 0;
        do
        {
            //Performe Some Operation. By removing Speed increases
            var j = 10 + 10;
            j += 25;
            i++;
        } while (i <= max);
    }

    private static void WhileLoop(int max)
    {
        int i = 0;
        while (i <= max)
        {
            //Performe Some Operation. By removing Speed increases
            var j = 10 + 10;
            j += 25;
            i++;
        };
    }

    private static void ForLoop(int max)
    {
        for (int i = 0; i <= max; i++)
        {
            //Performe Some Operation. By removing Speed increases
            var j = 10 + 10;
            j += 25;
        }
    }

    private static void DisplayElapsedTime(TimeSpan ts)
    {
        string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
        Console.WriteLine(elapsedTime, "RunTime");
    }
}

and these are the results of a live demo on DotNetFiddle:

Do While Loop:
00:00:00.06

While Loop:
00:00:00.13

For Loop:
00:00:00.27

Mohit Dhawan
  • 543
  • 6
  • 11
  • @Fabio What I believe is I have given best from my side. I accept your help but what was so wrong in my example so that you voted me down. – Mohit Dhawan May 24 '18 at 09:45
  • The downvote isn't mine. You probably got it because, as a general rule, answers that consist only of an external link are considered of low quality (the link could always become invalid, and then the answer would be useless). Have a look at https://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers. My edit should prevent further downvotes. If the downvoter came back here now, they could revert it, but there's no guarantee they would. And in any case there's no way to find them. Sorry! – Fabio says Reinstate Monica May 24 '18 at 10:11
  • OK, I take my words back and help is always thankful. :) – Mohit Dhawan May 25 '18 at 07:18
0

I was wondering the same thing so i googled and ended up here. I did a small test in python (extremely simple) just to see and this is what I got:

For:

def for_func(n = 0):
    for n in range(500):
        n = n + 1

python -m timeit "import for_func; for_func.for_func()" > for_func.txt

10000 loops, best of 3: 40.5 usec per loop

While:

def while_func(n = 0):
    while n < 500:
        n = n + 1

python -m timeit "import while_func; while_func.while_func()" > while_func.txt

10000 loops, best of 3: 45 usec per loop

Niclas Lindgren
  • 542
  • 6
  • 23
0

They should be equal. The for loop you wrote is doing exactly the same thing that the while loop is doing: setting $i=0, printing $i, and incrementing $i at the end of the loop.

murgatroid99
  • 19,007
  • 10
  • 60
  • 95
0

That will depend on the language implementation of said loop, compiler and what not.

Most compiler will compile to the exact same executable code for example in CIL (.NET) they definitely do.

Source: vcsjones @ http://forums.asp.net/t/1041090.aspx

Either way, the body of the loop is where the processing time will be spent not the way you iterate.

jfrobishow
  • 2,897
  • 2
  • 27
  • 42
0

for loops are easier to parallelize than while loops using something like OpenMP

So if the code within the loop is sufficiently time-consuming, for loop and parallelize it.

For short snippets of code, you wouldn't want to parallelize since it'd take longer to spin up another thread (an expensive operation) than to simply finish the loop.. so either one seems to be about the same judging from the other answers.

mczarnek
  • 1,305
  • 2
  • 11
  • 24
-1

Isn't a For Loop technically a Do While?

E.g.

for (int i = 0; i < length; ++i)
{
   //Code Here.
}

would be...

int i = 0;
do 
{
  //Code Here.
} while (++i < length);

I could be wrong though...

Also when it comes to for loops. If you plan to only retrieve data and never modify data you should use a foreach. If you require the actual indexes for some reason you'll need to increment so you should use the regular for loop.

for (Data d : data)
{
       d.doSomething();
}

should be faster than...

for (int i = 0; i < data.length; ++i)
{
      data[i].doSomething();
}
Jeremy Trifilo
  • 456
  • 6
  • 11
-1

Depends on the language and most likely its compiler, but they should be equivalent in most languages.

Randolpho
  • 55,384
  • 17
  • 145
  • 179