Blog Post default image

Loops

Hands up if you love loops? Good stuff, loops make our lives simple, but they can also make your code amazingly slow if not done right. In JavaScript again we have a few very common loops that are defined for us.

  • for
  • for-in (slow)
  • do-while
  • while
  • for each (slow)

Yes that is right, the ‘for-in’, and the ‘for each’ loops are slow, avoid them altogether if you can, you are far better off not using them if you can get away with it, and I will explain why shortly.

Now onto the good loops, which is the fastest you may ask? Well none are significantly faster than the others, so use for, do-while and while all you want, but here are the ways in which we make these fast loops faster!

  • Decrease the amount of work done per iteration
  • Number of iterations

The above don’t vary by loop type! So they are extremely important to optimisation. Here is an example of slow loops and fast loops.

Slower Loops
 // for loop
 for (var i=0; i < values.length; i++) {
	process(values[i]);
 }

 // do >while loop
 var j=0;
 do {
	process(values[j++]);
 } while (j < values.length);
 // j < values.length is equivalent to:  j < values.length <strong>and</strong> j < values.length == true


 // while loop
 var k=0;
 while (k < values.length) {
	process(values[k++]);
 };

This first loop is slow because you have a terminal condition being evaluated each time (i < values.length) that is also looking up a property type, an incremental value being evaluated each time (i++) and of course the body processing the value (process(values[i]);).

Faster loops
 // Local var

 var len = values.length


 // for loop
 for (var i=len; i--) {
	process(values[i]);
 }


 // do >while loop
 var j = len-1;
 do {
	process(values[j]);
 } while (j--);
 // now the condition is equivalent to 'j-- == true'

 // while loop
 var k=len;
 while (k--) {
	process(values[k]);
 }

Here we have basically flipped the loops, going from the last item in the array to zero, allowing us to remove extra work in the terminal conditions. These loops are around 50% faster than the ones above. They use less object property lookups by assigning a local variable (var len = values.length), and have less work to do evaluating the terminal conditions.

A note of for each loops

Typical for each loop
values.forEach(function(value, index, array) {
	process(value)
});

The problems here are

  • Your introducing an additional function
  • Now remember functions require execution context created, destroyed
  • Function also create an additional object in the scope chain
  • The function is a closure

These loops can take up to 8 times as long as a regular for loop! So really try hard to avoid function based iteration.

Pages: 1 2 3 4

2 Comments

  1. Very informative article. I guess it’s simple tips like this that make the difference between light and heavy code. Do these techniques apply to PHP too?

  2. CraigW says:

    I had a function which was taking over 37000ms to execute on IE6 (our company still insist on using IE6) and even 24,000ms in IE8 – Firefox executed the same function in 150ms.

    I discovered the cause – I was using a for – in to iterate around an array and it seems that IE is incapable of optimising for – in loops. I changed the code so it was using a for loop:

    OLD Code

    for (elementNo in myArray)
    {
    // for loop code
    }

    NEW Code

    var totalElements = myArray.length;
    for (var elementNo = 0; elementNo < totalElements; elementNo ++)
    {
    // for loop code
    }

    This reduced the IE6 time to 700ms (Firefox was 20ms faster).

Post a Comment