在前端做一直在做数据处理相关的工作,数据处理中循环是必不可少的
今天突发奇想做个 for forEach while 的性能测试

  • 通过 while 生成一个 10000/1000000/10000000 的数组(100000000 的时候,我在 8G Mac mini 的 Chrome 上直接崩溃了)
  • 同时测试 6 种循环情况

    • (1) 不缓存数组长度的情况下的 for 循环
    • (2) 缓存数组长度的情况下的 for 循环
    • (3) forEach 通过函数的第一个参数去直接访问数组的每一项
    • (4) forEach 通过函数的第二个参数作为数组的索引去访问
    • (5) while 循环
    • (6) do...while 循环
  • 测试环境

    • 8G Mac mini Chrome 每组测试 5 遍取平均
    • 4G Win10 Chrome 每组测试 7 遍,去掉最高和最低取平均

Mac 上是在公司测的,发现有些数据误差太大,所以在 Win 上每组多测两遍
为了减少其它因素的影响,把所有用到的变量的声明和初始化都放到了 console.time 外面了
加粗各行均为上面的平均值

测试数据(单位均是:ms)

1 for 2 for len 3 forEach 4 forEach i 5 while 6 do while
Mac: 10000
1.744ms 3.680ms 0.963ms 10.112ms 8.805ms 3.088ms
2.135ms 2.704ms 1.125ms 1.555ms 4.723ms 5.896ms
2.051ms 1.623ms 1.936ms 3.406ms 3.130ms 1.996ms
1.924ms 2.790ms 1.067ms 2.145ms 3.200ms 2.163ms
2.144ms 2.943ms 2.256ms 4.315ms 3.496ms 2.132ms
1.9996 2.748 1.4694 4.3066 4.6708 3.0523
Mac: 1000000
95.818ms 28.147ms 56.265ms 53.964ms 35.210ms 30.676ms
96.923ms 29.883ms 73.368ms 51.744ms 36.963ms 24.614ms
96.963ms 30.440ms 70.619ms 51.698ms 36.276ms 23.813ms
104.881ms 29.197ms 62.880ms 52.710ms 39.745ms 25.761ms
110.852ms 33.685ms 78.202ms 50.871ms 31.278ms 28.382ms
110.0874 30.2704 68.2668 52.1974 35.8944 26.6492
Mac: 10000000
1001.905ms 663.581ms 499.389ms 814.319ms 680.203ms 657.512ms
1025.942ms 771.186ms 602.182ms 530.644ms 740.030ms 822.920ms
1040.528ms 718.637ms 466.101ms 508.975ms 745.391ms 791.998ms
1034.220ms 694.250ms 485.827ms 562.011ms 640.886ms 773.209ms
1064.443ms 686.556ms 553.758ms 498.901ms 743.777ms 619.291ms
1033.4076 706.842 521.4514 582.97 710.0574 732.986
Win: 10000
0.996ms 1.170ms 1.724ms 1.815ms 0.771ms 1.735ms
1.244ms 0.664ms 1.147ms 1.087ms 1.030ms 1.865ms
1.156ms 3.067ms 0.536ms 1.068ms 0.556ms 0.442ms
0.680ms 2.958ms 0.587ms 0.600ms 0.769ms 0.506ms
0.684ms 2.936ms 0.614ms 0.682ms 0.895ms 0.457ms
0.678ms 2.903ms 0.431ms 0.750ms 1.112ms 0.458ms
0.683ms 2.962ms 0.437ms 0.603ms 0.999ms 0.469ms
0.8398 2.5858 0.6642 0.838 0.8928 0.725
Win: 1000000
66.494ms 32.518ms 45.310ms 50.130ms 41.062ms 45.139ms
37.196ms 30.383ms 44.974ms 49.845ms 36.146ms 35.053ms
38.345ms 38.673ms 48.223ms 55.696ms 92.926ms 35.189ms
35.580ms 22.810ms 50.901ms 51.598ms 33.785ms 29.506ms
62.227ms 24.367ms 49.142ms 50.095ms 42.194ms 40.974ms
35.819ms 22.516ms 49.199ms 49.961ms 33.729ms 35.801ms
35.918ms 23.919ms 48.414ms 51.732ms 42.393ms 57.818ms
41.901 26.7994 48.0576 50.7032 39.116 38.4312
Win: 10000000
658.166ms 340.854ms 618.050ms 452.447ms 542.498ms 497.274ms
567.903ms 216.552ms 596.438ms 422.032ms 399.972ms 490.728ms
606.825ms 310.089ms 452.573ms 963.005ms 491.967ms 363.201ms
556.882ms 212.453ms 436.831ms 787.031ms 438.829ms 354.112ms
670.299ms 482.667ms 412.817ms 638.142ms 342.891ms 495.724ms
867.215ms 229.437ms 433.750ms 612.873ms 364.820ms 498.095ms
776.929ms 208.486ms 422.660ms 595.952ms 362.419ms 504.568ms
656.0244 261.877 468.4504 617.289 411.6014 469.0044

统计汇总
统计汇总
10000
1000000
10000000

可能有些外部因素影响,从本次测试结果中可以看出来,在进行万级以内的数组操作用 缓存数据长度的 for 循环并没有优势,虽然耗时都很短可以忽略,forEach 更胜一筹。
在百万级的数组中,缓存数组长度的 for 循环占明显优势,whiledo while 也都不相上下,除了没缓存长度的 for 循环不稳定,其它的都还比较稳定。
在千万级的数组中,只有 forEach 的比较稳定而且效率算是比较高的。
小结一下,总体来说 forEach 效率还算比较不错的,在进行万级别的数组操作效率可以不用考虑,而比较差异的是 没有缓冲长度的 for 循环反而比缓冲了的效率高

最后附上测试源码,大家可以自己电脑上测试一下,可以分享一下测试结果

测试源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>循环效率测试</title>
</head>
<body>
<select id="number">
<option value="10000">10000</option>
<option value="1000000">1000000</option>
<option value="10000000">10000000</option>
</select>
<button id="go-btn">走起来</button>

<script>
var number = document.getElementById('number');
document.getElementById('go-btn').addEventListener('click', function(){
var arr = [];
var i = 0;
while(i < Number(number.value)){
i++;
arr.push(i);
}

var temp1 = [];
var j = 0;
console.time('>>>--- for --->');
for(; j < arr.length; j++){
temp1.push(arr[i]);
}
console.timeEnd('>>>--- for --->');
console.log(temp1.length);

var temp2 = [];
var k = 0;
var kLen = arr.length
console.time('>>>--- for len --->');
for(; k < kLen; k++){
temp2.push(arr[k]);
}
console.timeEnd('>>>--- for len --->');
console.log(temp2.length);

var temp3 = [];
console.time('>>>--- forEach --->');
arr.forEach(function(val){
temp3.push(val);
});
console.timeEnd('>>>--- forEach --->');
console.log(temp3.length);

var temp4 = [];
console.time('>>>--- forEach index --->');
arr.forEach(function(val, index){
temp4.push(arr[index]);
});
console.timeEnd('>>>--- forEach index --->');
console.log(temp4.length);

var temp5 = [];
var x = 0;
var xLen = arr.length;
console.time('>>>--- while --->');
while(x < xLen){
x++;
temp5.push(arr[x]);
}
console.timeEnd('>>>--- while --->');
console.log(temp5.length);

var temp6 = [];
var y = 0;
var yLen = arr.length;
console.time('>>>--- do while --->');
do{
y++;
temp6.push(arr[y]);
}while(y < yLen)
console.timeEnd('>>>--- do while --->');
console.log(temp6.length);
});
</script>

</body>
</html>