Duff's Device for JavaScript

Nicholas Zakas in his book "High Performance JavaScript" has mentioned about Jeff Greenberg's JavaScript implementation of Tom Duff's original technique of unrolling loop bodies in order to let each iteration perform job of many iterations.

for (var i = 0, loopLen = items.length; i < loopLen; i++) {
    process(items[i]);
}

can be rewritten with this technique as:

var arrLen = items.length;
var loopLen = Math.floor(arrLen / 8),
    startAt = arrLen % 8,
    i = 0;

do {
    switch (startAt) {
        case 0: process(items[i++]);
        case 7: process(items[i++]);
        case 6: process(items[i++]);
        case 5: process(items[i++]);
        case 4: process(items[i++]);
        case 3: process(items[i++]);
        case 2: process(items[i++]);
        case 1: process(items[i++]);
    }

    startAt = 0;
} while (--loopLen)

Suppose, the "items" array contains 10 items. The first iteration will call "process()" 2 times - 'case 2:' and 'case 1:'. (Note that the break statement has been excluded intentionally). The second iteration will invoke "process()" 8 times. This has reduced the number of iterations from 10 to just 2.

Jeff Greenberg has even improved this pattern further by having a separate loop construct for the first part of the iterations and totally getting rid of the 'switch' statement thereon.
var arrLen = items.length;
var i = arrLen % 8;

while (i) {
    process(items[i--]);
}

i = Math.floor(arrLen / 8);

while (i) {
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
}

Though for smaller number of iterations there isn't a significant gain on performance, it is seen that, at 500,000 iterations the execution time is up to 70% less than a regular loop.

Posterous theme by Cory Watilo