javascript数组遍历的几种常用方法性能分析对比

前言:

数组遍历有很多种方法,虽然不同方法有不同的特性及适用环境,除了普通飞for循环之外,for...in能直接输出数组元素的索引,for...of能直接输出数组元素的值,map则可以直接生成新的数组,forEach则可以遍历修改元祖元素的值。那么这些方法在性能上相比怎么样呢?

验证:

为了验证这个问题,构造了一个10000条数据的数组,然后使用不同的方法对数组进行遍历输出,通过每种方法遍历前后的时间戳来计算每种方法执行耗费的时间,整理如下:

如上,使用谷歌浏览器进行了10次实验,得出每种方法的执行时间(ms),其中优化版for循环是使用临时变量,将长度缓存起来,避免重复获取数组长度。

大致可以看出性能最优的要数优化版的for循环了,其次是for...of和for...in循环,最差的集中在forEach循环,其次是map遍历,普通的for循环则处于中间。

验证代码:

 1 <!DOCTYPE html>
 2 <html>
 3 
 4     <head>
 5         <meta charset="UTF-8">
 6         <title></title>
 7     </head>
 8 
 9     <body>
10         <script>
11             //构造数组
12             var arr = [];
13             for(let i = 0; i < 10000; i++) {
14                 arr[i] = {
15                     detailImgUrl: "https: //ss0.bdstatic.com/k4oZeXSm1A5BphGlnYG/skin/71.jpg?2"
16                 }
17             }
18             //console.log(arr)
19             //数组遍历验证
20             const {log} = console;
21             var newArr = []
22             //方法1 普通for循环
23             let time = new Date().getTime();
24             for(i = 0; i < arr.length; i++) {
25                 document.write(arr[i].detailImgUrl)
26             }
27             let time1 = new Date().getTime()
28             log(time1 - time, "普通for循环")
29             newArr.push(time1 - time)
30             //方法2 优化版for循环
31             for(j = 0, len = arr.length; j < len; j++) {
32                 document.write(arr[j].detailImgUrl)
33             }
34             let time2 = new Date().getTime()
35             log(time2 - time1, "优化版for循环")
36             newArr.push(time2 - time1)
37             //方法3 forEach循环
38             arr.forEach(item => {
39                 document.write(item.detailImgUrl)
40             })
41             let time3 = new Date().getTime()
42             log(time3 - time2, "forEach循环")
43             newArr.push(time3 - time2)
44             //方法4 for in循环
45             for(k in arr) {
46                 document.write(arr[k].detailImgUrl)
47             }
48             let time4 = new Date().getTime()
49             log(time4 - time3, "for in循环")
50             newArr.push(time4 - time3)
51             //方法5 for of循环
52             for(k of arr) {
53                 document.write(k.detailImgUrl)
54             }
55             let time5 = new Date().getTime()
56             log(time5 - time4, "for of循环")
57             newArr.push(time5 - time4)
58             //方法6 map遍历
59             arr.map(v => {
60                 document.write(v.detailImgUrl)
61             })
62             let time6 = new Date().getTime()
63             log(time6 - time5, "map遍历")
64             newArr.push(time6 - time6)
65             newArr.forEach(value => {
66                 document.write("<p>" + value + "</p>")
67             })
68         </script>
69     </body>
70 
71 </html>

注意事项:

1.为了增加实验的复杂度,以对象作为数组元素,且以比较长的字符串作为对象的一个元素,使用各种数组遍历方法去遍历对象元素的子元素;

2.为了更真实的反应各种遍历方法的性能,建议数组长度在1000以上,实验次数在10次以上,这样才能得出更真实的对比结果;

3.测试数据比较大,可以先用普通的for循环生成数组,然后直接使用数组进行实验;

总结:

对于前边的实验结果,也只有数据量比较大的情况下才会比较明显。通常情况下前端一次处理的数组也就几十条,将各结果按比例折算,最差的也就10.89ms,最好的8.08ms,相差了2~3ms左右,这个几乎可以忽略不计了。所以说非大数据的情况下如果对性能要求不是太严格就不用太纠结了,根据自己的习惯使用就好。当然追求性能的同学可以在实际开发中选择性能比较好的方法进行使用。

 

posted on 2019-05-06 09:55  逍遥云天  阅读(1833)  评论(0编辑  收藏  举报

导航