展开循环。
当循环的次数确定时,消除循环并使用多次函数调用往往更快。
当循环的次数不确定时,可以使用Duff装置来优化。
Duff装置的基本概念是通过计算迭代的次数是否为8的倍数将一个循环展开为一系列语句。
// Jeff Greenberg for JS implementation of Duff's Device
// 假设:values.length 0
function process(v) {
alert(v);
}
var values = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17];
var iterations = Math.ceil(values.length / 8);
var startAt = values.length % 8;
var i = 0;
do {
switch(startAt) {
case 0 : process(values[i++]);
case 7 : process(values[i++]);
case 6 : process(values[i++]);
case 5 : process(values[i++]);
case 4 : process(values[i++]);
case 3 : process(values[i++]);
case 2 : process(values[i++]);
case 1 : process(values[i++]);
}
startAt = 0;
}while(--iterations 0);
如上展开循环可以提升大数据集的处理速度。接下来给出更快的Duff装置技术,将do-while循环分成2个单独的循环。(注:这种方法几乎比原始的Duff装置实现快上40%。)
// Speed Up Your Site(New Riders, 2003)
function process(v) {
alert(v);
}
var values = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17];
var iterations = Math.floor(values.length / 8);
var leftover = values.length % 8;
var i = 0;
if(leftover 0) {
do {
process(values[i++]);
}while(--leftover 0);
}
do {
process(values[i++]);
process(values[i++]);
process(values[i++]);
process(values[i++]);
process(values[i++]);
process(values[i++]);
process(values[i++]);
process(values[i++]);
}while(--iterations 0);
针对大数据集使用展开循环可以节省很多时间,但对于小数据集,额外的开销则可能得不偿失。