Performance of JavaScript Looping Techniques

23. December 2009

I was reading Paul Irish’s (@paul_irish) recent blog post entitled Updates from all around – Dec 2009 and I saw an interesting for loop syntax that he referenced…

for (var i = -1, len = arr.length; ++i < len; ) // the cool guy loop

He went on further to show some performance results of the above syntax compared to the old for loop style most of us are used to.

I thought this was interesting, so I decided to put my own suite of tests together to exercise various looping techniques and determine their average performance. 

Note: In my test methods I wanted to simulate a semi-real world scenario where an array would be used and in the loop an item from the array would be referenced.

The test runner accepts the size of the array to be looped and the number of times you want the test to be ran. The end result will print the average time (in milliseconds) the test took to the console.

Here are the functions that I am profiling…

function oldAndBusted() {
   for (var i = 0; i < arr.length; ++i) { arr[i]; }
}

function oldAndBustedCached() {
   var arrLength = arr.length;
   for (var i = 0; i < arrLength; ++i) { arr[i]; }
}

function coolGuyLoop() {
   for (var i = -1, len = arr.length; ++i < len; ) { arr[i]; } 
}

function coolGuyLoopCached() {
   var arrLength = arr.length;
   for (var i = -1, len = arrLength; ++i < len; ) { arr[i]; } 
}

function whileLoopCached() {
   var i = 0, arrLength = arr.length;
   while (i < arrLength) { arr[i]; i++; }
}

function reverseWhileLoop() {
   var i = arr.length; 
   while (i--) { arr[i]; }
}

Here are the results of my testing...

JavaScriptLoopPerformance2

You can view, run, and edit the tests for yourself on JS Bin (jsbin.com/uvoye/edit)

From a speed perspective here is how the various looping techniques ranked against each other (#1 being fastest & #6 being slowest)

  1. Reverse While Loop
  2. The Cool Guy Loop
  3. Old and Busted Cached
  4. While Loop Cached
  5. The Cool Guy Loop Cached
  6. Old and Busted
    I was actually surprised that ‘the cool guy loop cached’ was slower than ‘the cool guy loop’. I was thinking if I saved off the array length into a variable that it would speed up the loop instead of accessing the length every time.
    Note: If you have any variations of a loop you would like to see in my test cases, please provide a comment with your suggestion.

cooltext439924698 cooltext439925164

Note: The above performance times were ran using FireFox 3.6 Beta 4 using FireBug 1.5X.0b8 on an Intel Quad Core 2.00GHz Laptop running Win7.

Blog


Comments

James Taylor
James Taylor
12/23/2009 5:59:36 PM #
Just tried this for 1000 iterations and the results are different again.
12/23/2009 6:07:08 PM #
JavaScript performance profiling is a tricky business.

There are a lot of factors to consider such as

* Browser type (IE, FF, Chrome, Safari, etc...)
* Browser version
* Computer speed
* What other programs you might be running
* Etc...

You might encounter different perf results, but in the end the ranking of which is faster should be consistent. However, the ranking could be different across different browsers. As I mentioned at the end of the blog post I did my testing with...

The above performance times were ran using FireFox 3.6 Beta 4 using FireBug 1.5X.0b8 on an Intel Quad Core 2.00GHz Laptop running Win7.
12/23/2009 9:00:55 PM #
In your cached loops, declare the var inside the loop rather than above it - I would think this would speed up performance since javascript won't have to look outside the scope of the loop to find the value of the cached array length:

function oldAndBustedCached()
{
  for (var i = 0, len = arr.length; i < len; ++i) { arr[i]; }
}

function coolGuyLoopCached()
{
  for (var i = -1, len = arr.length; ++i < len; ) { arr[i]; }
}
12/23/2009 9:33:01 PM #
@Jon,

Good suggestion, I updated my tests and ran them again, but the results were that the inlined cached length actually ran slower than without the caching! I ran the tests twice just to make sure.

See the screenshot...  http://www.twitpic.com/utf9t
12/23/2009 9:48:59 PM #
I completely agree with Jon Trefla's view.
Eric
Eric
12/26/2009 10:47:02 PM #
var i = -1, len = arr.length; does indeed store the array length in a variable... you have it called len and in doing so it does not reference the array.length property each time. That and the cached version are the same thing.
12/28/2009 12:36:45 AM #
Just to add some results (100 Iterations) on a 2GB DDR2 Ram, 1.8 Ghz Single Core Laptop with FF 3.5.6 and FireBug 1.4.5:

1. reverse while loop: 17.15 ms
2. the cool guy loop cached: 19.04 ms
3. while loop cached: 19.51 ms
4. old and busted cached: 19.59 ms
5. the cool guy loop: 19.64 ms
6. old and busted: 23.89 ms


12/31/2009 10:19:00 AM #
Here's a foreach-style loop that's a heck of a lot faster

http://jsbin.com/otina/edit
1/1/2010 12:20:41 AM #
@Joel,

It is very fast because the loop isn't looping ;) Try adding a console.log statement and you'll notice that it won't execute(). You can add some console.logs to the other functions to see that they do loop. Note: You might want to lower the iterations to 1 and array size to 5.

For more information about the for-each method (and tons of other array information) check out...

www.hunlock.com/blogs/Mastering_Javascript_Arrays
Joel
Joel
1/1/2010 10:22:08 PM #
Ack! Didn't realize the test array didn't have any values in it. That explains the fishiness I was sorta concerned about when I saw those obscenely low numbers Smile

Here's a more comprehensive loop benchmarking suite btw:
blogs.sun.com/greimer/resource/loop-test.html
1/11/2010 9:35:13 AM #
haha.. i'd looked through you code over and over and was very perplexed by your results. Then I realised your arrays have nothing in them! Post back the results when you fix it Smile

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading



Olark Livehelp