循环基本上算是当前项目中不可或缺的部分,但是过多的循环会带来一定的性能开销,增加总体运行时间。而减少迭代次数能够优化性能。
Duff’s Device
- 代码的思路就是每次循环都执行八次函数,这样很明显会减少迭代的次数。不过,只有在迭代次数比较多时,才能够有明显的效率提升。
var counter = Math.floor(items.length/8)
startAt = items.length % 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(--counter)
- 改进版本,也是我所用的版本
var startAt = items.length % 8;
let i = 0 // 用来保存执行的次数
// 余数部分循环
if (startAt > 0) {
do {
process(i++)
} while (--startAt > 0)
}
var counter = Math.floor(items.length / 8);
do {
process(i++)
process(i++)
process(i++)
process(i++)
process(i++)
process(i++)
process(i++)
process(i++)
} while (--count > 0)
- 同时与for循环进行比较,取5次的平均值,可以发现for用时0.7890625ms,而duff用时0.3677734375,这还是处于没有在循环体中增加任何的代码的情况下。
const arr = []
for (let i = 0; i < 10000; i++) {
arr.push(i)
}
let count = Math.floor(arr.length / 8)
let startAt = arr.length % 8
let i = 0 // i 用来保存执行的次数
console.time('test')
// 余数部分循环
if (startAt > 0) {
do {
process()
} while (--startAt > 0)
}
// 主体循环
do {
process()
process()
process()
process()
process()
process()
process()
process()
} while (--count > 0)
console.timeEnd('test') // 0.3677734375
function process() {}
const arr = []
for (let i = 0; i < 10000; i++) {
arr.push(i)
}
console.time('test')
for(let i = 0; i < 10000; i++) { //0.7890625
process()
}
console.timeEnd('test')