Loop Optimization--Part 3 of Chapter 10 from Speed Up Your Site (2/6)--WebReference.com | WebReference

Loop Optimization--Part 3 of Chapter 10 from Speed Up Your Site (2/6)--WebReference.com

To page 1current pageTo page 3To page 4To page 5To page 6
[previous] [next]

Speed Up Your Site, Chapter 10: Optimizing JavaScript for Execution Speed

Hoist Loop-Invariant Code

Move loop-invariant code out of loops (otherwise called coding motion out of loops) to speed their execution. Rather than recomputing the same value in each iteration, move it outside the loop and compute it only once. So instead of this:

for (i=0;i<iter;i++) {
  d=Math.sqrt(y);
  j+=i*d;
}

Do this:

d=Math.sqrt(y);
for (i=0;i<iter;i++) {
  j+=i*d;
}

Reverse Loops

Reversing loop conditions so that they count down instead of up can double the speed of loops. Counting down to zero with the decrement operator (i--) is faster than counting up to a number of iterations with the increment operator (i++). So instead of this (see Listing 10.9):

Listing 10.9 A Normal for Loop Counts Up

function loopNormal() {
  for (var i=0;i<iter;i++) {
    // do something here
  }
}

Do this (see Listing 10.10):

Listing 10.10 A Reversed for Loop Counts Down

function loopReverse() {
  for (var i=iter;i>0;i--) {
    // do something here
  }
}

Flip Loops

Loop flipping moves the loop conditional from the top to the bottom of the loop. The theory is that the do while construct is faster than a for loop. So a normal loop (see Listing 10.9) would look like this flipped (see Listing 10.11):

Listing 10.11 A Flipped Loop Using do while

function loopDoWhile() {
var i=0;
do 
{
  i++;
}
while (i<iter);
}

In JavaScript, however, this technique gives poor results. IE 5 Mac gives inconsistent results, while IE and Netscape for Windows are 3.7 to 4 times slower. The problem is the complexity of the conditional and the increment operator. Remember that we're measuring loop overhead here, so small changes in structure and conditional strength can make a big difference. Instead, combine the flip with a reverse count (see Listing 10.12):

Listing 10.12 Flipped Loop with Reversed Count

function loopDoWhileReverse() {
var i=iter;
do 
{
  i--;
}
while (i>0);
}

This technique is more than twice as fast as a normal loop and slightly faster than a flipped loop in IE5 Mac. Even better, simplify the conditional even more by using the decrement as a conditional like this (see Listing 10.13):

Listing 10.13 Flipped Loop with Improved Reverse Count

function loopDoWhileReverse2() {
var i=iter-1;
do 
{
  // do something here
}
while (i--);
}

This technique is over three times faster than a normal for loop. Note the decrement operator doubles as a conditional; when it gets to zero, it evaluates as false. One final optimization is to substitute the pre-decrement operator for the post-decrement operator for the conditional (see Listing 10.14).

Listing 10.14 Flipped Loop with Optimized Reverse Count

function loopDoWhileReverse3() {
var i=iter;
do 
{
  // do something here
}
while (--i);
}

This technique is over four times faster than a normal for loop. This last condition assumes that i is greater than zero. Table 10.2 shows the results for each loop type listed previously for IE5 on my Mac PowerBook.

Table 10.2 Loop Optimizations Compared

 

Normal

Do While

Reverse

Do While Reverse

Do While Reverse2

Do While Reverse3

Total time (ms)

2022

1958

1018

932

609

504

Cycle time (ms)

0.0040

0.0039

0.0020

0.0018

0.0012

0.0010


To page 1current pageTo page 3To page 4To page 5To page 6
[previous] [next]

Created: January 27, 2003
Revised: January 27, 2003

URL: http://webreference.com/programming/optimize/speedup/chap10/3/2.html