1.数组循环遍历方法
javascript传统的数组遍历有for循环,while循环,以及for-in。
本篇文章要比较的是以下几种循环遍历方法:
遍历方式 | 备注 |
---|---|
正向for循环 | |
逆向for循环 | 减少一次控制条件比较,性能理论上比正向for循环稍好 |
while循环 | |
for-in循环 | 理论性能最差 |
for-each循环 | |
duff's device 循环 | 利用并发,理论性能最好wiki 介绍 |
2.代码:
var number = 100000;//array大小
var iteranum = 100;//迭代次数 var array = []; for(let i=0;i<number;i++) { array[i] = i+1; } //test cicle var len = array.length; //正常for循环 console.time('normal for'); for(let k=0;k<iteranum;k++) { for(let i=0;i<len;i++) { array[i]+1; } } console.timeEnd('normal for'); //倒序for循环 console.time('reverse for'); for(let k=0;k<iteranum;k++) { for(let i=len-1;i--;) { array[i]+1; } } console.timeEnd('reverse for'); //while循环 console.time('while'); for(let k=0;k<iteranum;k++) { let i=0; while(i<len) { array[i]+1; i++; } } console.timeEnd('while'); //for-in循环 console.time('for-in'); for(let k=0;k<iteranum;k++) { for(let i in array) { array[i]+1; } } console.timeEnd('for-in'); //for each 循环 console.time("for each"); for(let k=0;k<iteranum;k++) { array.forEach(function(e){ e+1; }); } console.timeEnd("for each"); //duff's device 循环 console.time("device's device"); for(let k=0;k<iteranum;k++) { let j = len % 8; let templen = len-1; while(j){ j--; array[templen--]+1; } j = Math.floor(len / 8); while(j){ j--; array[templen--]+1; array[templen--]+1; array[templen--]+1; array[templen--]+1; array[templen--]+1; array[templen--]+1; array[templen--]+1; array[templen--]+1; } } console.timeEnd("device's device");
3.实验步骤
- 实验环境 ,操作系统 windows server 2016, node 8.0,cpu E5-1630 v3 @ 3.7GHz ,内存16G
- 数组内的数据操作很简单,就是将每一个元素加1,但是不覆盖原先的数据
- 实验将采取多点采样,数组样本大小分别设置为:1000,10000,100000,1000000(1000次以下性能差距不大)
- 对每种方式分别进行100次仿真叠加,最后取100次的仿真结果平均数,作为该实验数据的最终结果。
- 将结果以折线图的形式展示
4.实验结果
(1)结果表格(单位:微秒)
遍历方式/Item数量 | 1000 | 10000 | 100000 | 1000000 |
---|---|---|---|---|
正向for循环 | 43 | 456 | 3840 | 35679 |
逆向for循环 | 37 | 378 | 3604 | 33488 |
while循环 | 66 | 296 | 2294 | 20576 |
for-in循环 | 87 | 958 | 32443 | 401017 |
for-each循环 | 64 | 395 | 4272 | 32435 |
duff's device 循环 | 20 | 235 | 2137 | 16364 |
(2)结果直方图
为了结果展示方便,将所有数据都进行了log转换
![](http://upload-images.jianshu.io/upload_images/4281658-6eac60a1c76f01ac.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
几种数组循环的性能对比
横向为数组元素大小,纵向为运行时间(微秒)的log值。
上图可见,duff's device方式执行效率一直很高,而for-in方式的效率一直很低,正向for和逆向for效率相差不大,逆向for稍微占优势。
5.总结
-
- 总体来说for循环和for-each性能相当,在小数据量时也与while性能相当。for-in性能最差,duff's device性能最好。大数据量时,while性能优于for循环和for-each循环。
- 对于数据量不大的循环(<1000),不用考虑使用哪一种性能更好,可读性是第一位
- 对于有较大数据量的循环和遍历,如果性能不是瓶颈,那么普通的for循环(或者while,do-while,for-each)就可以了,毕竟可读性强。
- 对于较大的数据量,如果array的循环操作已经成为瓶颈,或者性能非常重要,那么可以采用duff's device方案。
- 任何时候都不建议使用for-in,除非必须要用