JavaScript Loop Test

3rd June 2006

Today I set out to answer the oh-so exciting question “What is the fastest way to create a loop in JavaScript?” After some tedious exhaustive, cross browser testing these are my results…

My test was pretty simple — create an array and use a variety of different loops to push 1,000,000 1’s onto it using some different browsers. The value 1,000,000 was mostly chosen because it was a nice round number and also it was about as far as I could go before I started seeing timeout errors in Internet Explorer.

Each test was repeated 10 times in each browser. To get a rough feel for “overall” performance the results from all 3 browsers are also averaged on each test. All the times quoted are in milliseconds. The fastest mean, median, minimum and maximum test scores for each browser are emphasised in the tables below. For comparison with the basic loops I’ve added an extra table showing the same tests performed using Duff’s Device.

for loop counting up, post-incrementing the counter

for (var i = 0; i < n; i++) { 

}
Times for a for loop counting up, probably the most common usage?
IE 6 Firefox 1.5 Opera 9 Overall
Mean 6568.9 3009.7 2531.1 4036.6
Median 6563 3016 2484 4021
Min 6500 2969 2250 3906.3
Max 6641 3032 2984 4219

for loop counting up, pre-incrementing the counter

for (var i = 0; i < n; ++i) { 

}
A for loop counting up again, but pre-incrementing the counter.
IE 6 Firefox 1.5 Opera 9 Overall
Mean 6564 3028.1 2523.4 4038.5
Median 6563 3016 2484.5 4021.7
Min 6531 3000 2266 3932.3
Max 6593 3079 2859 4177

for loop counting down, post-decrementing the counter

for (var i = n; i != 0; i--) { 

}
Times for a for loop that counts down.
IE 6 Firefox 1.5 Opera 9 Overall
Mean 6484.3 3079.6 2509.4 4024.1
Median 6476.5 3078 2398.5 3984.3
Min 6406 3031 2359 3932
Max 6562 3156 2797 4171.7

for loop counting down, pre-decrementing the counter

for (var i = n; i != 0; --i) {

}
Using a for loop to count down again, this time pre-decrementing the counter.
IE 6 Firefox 1.5 Opera 9 Overall
Mean 6481.3 3057.7 2439.1 3992.7
Median 6484 3047 2351.5 3960.8
Min 6453 3032 2297 3927.3
Max 6515 3109 2875 4166.3

while loop counting up, post-incrementing the counter

var i = 0;
while (i++ < n) { 

}
Times for a while loop that counts up.
IE 6 Firefox 1.5 Opera 9 Overall
Mean 6462.4 2973.3 2492.3 3976
Median 6453 2969 2351.5 3924.5
Min 6390 2937 2297 3874.7
Max 6578 3015 2859 4150.7

while loop counting up, pre-incrementing the counter

var i = 0;
++n; // add 1 or we’ll exit the loop one iteration too early
while (++i < n) {

}
Another while loop counting up pre-incrementing the counter.
IE 6 Firefox 1.5 Opera 9 Overall
Mean 6436 2985.8 2467.2 3963
Median 6429.5 2984 2321 3911.5
Min 6421 2969 2265 3885
Max 6500 3015 2829 4114.7

while loop counting down, post-decrementing the counter

while (n--) {

}
A while loop counting down.
IE 6 Firefox 1.5 Opera 9 Overall
Mean 6437.6 2947 2342.3 3909.0
Median 6430 2938 2218.5 3862.2
Min 6360 2906 2110 3792
Max 6562 3016 2688 4088.7

while loop counting down, pre-decrementing the counter

++n; // add 1 or we’ll exit the loop one iteration too early
while (--n) { 

}
Another while loop counting down, pre-decrementing the counter.
IE 6 Firefox 1.5 Opera 9 Overall
Mean 6407.8 2929.5 2257.8 3865.0
Median 6398.5 2922 2218.5 3846.3
Min 6328 2906 2156 3796.7
Max 6469 2969 2641 4026.3

12th June 2006 — Some updates — “Duff’s Device”

Optimizing JavaScript for Execution Speed suggests that significant performance benefits can be achieved using “Duff’s Device”, this technique reduces the number of iterations required using loop unrolling. Here’s the function tested:

function duffsDevice(n) {
    var arr = [];
    var i = n % 8;

    if (i > 0) {
        do {
            arr.push(1);
        } while (--i);
    }

    var n = parseInt(n / 8);
    do {
        arr.push(1);
        arr.push(1);
        arr.push(1);
        arr.push(1);
        arr.push(1);
        arr.push(1);
        arr.push(1);
        arr.push(1);
    } while (--n);
}
Execution times when using Duff’s Device.
IE 6 Firefox 1.5 Opera 9 Overall
Mean 6384.3 2831.2 2129.7 3781.7
Median 6375 2820.5 2008 3734.5
Min 6328 2781 1860 3656.3
Max 6453 2953 2578 3994.7

Some Conclusions

The most striking observation is how slow IE is compared with the more modern browsers, (though the differences between browsers seems to be more to do with the array, rather than the loops) however that aside and despite the decidedly non-scientific test conditions there are perhaps a couple of interesting points.

These results are perhaps shown more clearly in the following graph:

This shows a comparison of the times taken by the different variations of the loops (averaged over all 3 browsers). The yellow bars indicate the range between the averaged min and max times.

Browsers tested (all on Windows XP):

Permalink. Posted on 3rd June 2006 in Browsers, JavaScript.

Comments

  1. Good work Andrew. Interesting results, particularly lack of much difference between the for loop variants.

    I wonder if more tests would show any clearer differences? Not that I am belittling your efforts here, these results certainly give some useful indications.

    # Posted by Stuart Colville on 5th June 2006.

  2. Yeah, you might be right. In particular I'm wondering if the last 2 while loops were faster because of how the exit condition is written rather than just because they count down. Might be worth some further investigation!

    # Posted by Andy on 6th June 2006.

  3. I am delighted to see that the fastest is also visually the cleanest (even if it is not the most standard.) A tasty coincidence.

    # Posted by Tim McCormack on 10th June 2006.

  4. This is excellent! I've often wondered when writing your typical for loop if I was using the most efficient mechanism. Now I know something better. Thanks!

    # Posted by Clay on 10th June 2006.

  5. This is the stupidest test i've seen

    # Posted by paul martin on 11th June 2006.

  6. I'm not surprised having done these tests myself already years ago. From a practical point of view I usually use the while (n--) loop (when order doesn't matter):

    var ar = [1,2,3], n = ar.length;
    while (n--) alert(ar[n]);

    opposite to this because of obvious reasons:

    var ar = [1,2,3], n = ar.length;
    while (--n) alert(ar[n]);
    // problem is, we now miss ar[0];

    but when you are iterating arrays (which is the common reason to use these kind of loops) this seems to be faster still, just as long as you are sure none of the array-values will evaluate to false:

    var ar = [1,2,3], n = 0, el;
    while ((el = ar[n++])) alert(el);

    # Posted by Tino Zijdel on 11th June 2006.

  7. So I could gain 0.2 seconds on a 4 second loop? Whee, 5% savings! :7

    More interesting to me is the greater clarity in the while (n--){ } loop.

    # Posted by Rob on 11th June 2006.

  8. wow. That was one nerdy post.. im scared to read it :S

    # Posted by rotub on 12th June 2006.

  9. does anyone use a

    for(var i=0; arr[i]; i++) {…}

    style loop?

    # Posted by peteb on 10th July 2006.

  10. Interesting, however the for loop as the advantage that the variable is defined within the loop and not outside… the while loop might become a probleme with bigger codes [human errors]. Worth keeping in mind.

    # Posted by Ride on 14th September 2006.

  11. why all the pink?

    # Posted by m on 5th October 2006.

  12. Good stat, but what about this code:

    for (var a in array) { … }

    # Posted by Alex on 22nd February 2007.

Sorry, comments for this item are currently closed.

Of Interest

Hangouts

Listening