JS-循环性能测试
在前端做一直在做数据处理相关的工作,数据处理中循环是必不可少的
今天突发奇想做个 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
循环
- (1) 不缓存数组长度的情况下的
测试环境
- 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 | 0.771ms | 1.735ms | ||
1.147ms | 1.087ms | 1.030ms | |||
1.156ms | 0.536ms | 1.068ms | |||
0.680ms | 2.958ms | 0.587ms | 0.769ms | 0.506ms | |
0.684ms | 2.936ms | 0.614ms | 0.682ms | 0.895ms | 0.457ms |
2.903ms | 0.750ms | 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 | |||||
32.518ms | 45.310ms | 50.130ms | 41.062ms | 45.139ms | |
37.196ms | 30.383ms | 36.146ms | 35.053ms | ||
38.345ms | 48.223ms | 35.189ms | |||
22.810ms | 51.598ms | 33.785ms | |||
62.227ms | 24.367ms | 49.142ms | 50.095ms | 42.194ms | 40.974ms |
35.819ms | 49.199ms | 49.961ms | 35.801ms | ||
35.918ms | 23.919ms | 48.414ms | 51.732ms | 42.393ms | |
41.901 | 26.7994 | 48.0576 | 50.7032 | 39.116 | 38.4312 |
Win: 10000000 | |||||
658.166ms | 340.854ms | 452.447ms | 497.274ms | ||
567.903ms | 216.552ms | 596.438ms | 399.972ms | 490.728ms | |
606.825ms | 310.089ms | 452.573ms | 491.967ms | 363.201ms | |
212.453ms | 436.831ms | 787.031ms | 438.829ms | ||
670.299ms | 638.142ms | 495.724ms | |||
229.437ms | 433.750ms | 612.873ms | 364.820ms | 498.095ms | |
776.929ms | 422.660ms | 595.952ms | 362.419ms | ||
656.0244 | 261.877 | 468.4504 | 617.289 | 411.6014 | 469.0044 |
统计汇总
可能有些外部因素影响,从本次测试结果中可以看出来,在进行万级以内的数组操作用 缓存数据长度的 for
循环并没有优势,虽然耗时都很短可以忽略,forEach
更胜一筹。
在百万级的数组中,缓存数组长度的 for
循环占明显优势,while
和 do 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
<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>