04.11.2015 Views

javascript

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Chapter 20: Best Practices<br />

This example assumes that there are only three items in the values array and simply calls process()<br />

directly on each item. Unrolling loops in this way eliminates the overhead of setting up a loop and<br />

processing a terminal condition, making the code run faster.<br />

If the number of iterations through the loop can ’ t be determined ahead of time, you may want to<br />

consider using a technique called Duff ’ s device. The technique is named after its creator, Tom Duff, who<br />

first proposed using it in the C programming language. Jeff Greenberg is credited with implementing<br />

Duff ’ s device in JavaScript. The basic idea of Duff ’ s device is to unroll a loop into a series of statements<br />

by calculating the number of iterations as a multiple of 8. Consider the following code example:<br />

//credit: Jeff Greenberg for JS implementation of Duff’s Device<br />

var iterations = Math.ceil(values.length / 8);<br />

var startAt = values.length % 8;<br />

var i = 0;<br />

do {<br />

switch(startAt){<br />

case 0: process(values[i++]);<br />

case 7: process(values[i++]);<br />

case 6: process(values[i++]);<br />

case 5: process(values[i++]);<br />

case 4: process(values[i++]);<br />

case 3: process(values[i++]);<br />

case 2: process(values[i++]);<br />

case 1: process(values[i++]);<br />

}<br />

startAt = 0;<br />

} while (--iterations > 0);<br />

This implementation of Duff ’ s device starts by calculating how many iterations through the loop need to<br />

take place by dividing the total number of items in the values array by 8. The ceiling function is then<br />

used to ensure that the result is a whole number. The startAt variable holds the number of items that<br />

wouldn ’ t be processed if the iterations were based solely on dividing by 8. When the loop executes for<br />

the first time, the startAt variable is checked to see how many extra calls should be made. For instance,<br />

if there are 10 values in the array, startAt would be equal to 2, so process() would be called only<br />

twice the first time through the loop. At the bottom of the loop, startAt is reset to 0 so that each<br />

subsequent time through the loop results in eight calls to process() . This unrolling speeds up<br />

processing of large datasets.<br />

The book Speed Up Your Site by Andrew B. King (New Riders, 2003) proposed an even faster Duff ’ s<br />

device technique that separated the do - while loop into two separate loops. Here’s an example:<br />

//credit: Speed Up Your Site (New Riders, 2003)<br />

var iterations = Math.floor(values.length / 8);<br />

var leftover = values.length % 8;<br />

var i = 0;<br />

if (leftover > 0){<br />

do {<br />

process(values[i++]);<br />

} while (--leftover > 0);<br />

}<br />

(continued)<br />

653

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!