Js 几种循环的比较

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
const TEST_SIZE = 10000000;
// 常用
let arr1 = (new Array(TEST_SIZE)).fill(1);
let target1 = [];
let iStart1 = (new Date()).getTime();
for (let i=0; i < arr1.length; i++) {
target1.push(arr1[i]);
}
let iEnd1 = (new Date()).getTime();
console.log('for:' +(iEnd1 - iStart1)+'ms');

// 取 len
let arr11 = (new Array(TEST_SIZE)).fill(1);
let target11 = [];
let iStart11 = (new Date()).getTime();
let len = arr11.length;
for (let i=0; i < len; i++) {
target11.push(arr11[i]);
}
let iEnd11 = (new Date()).getTime();
console.log('for-len:' +(iEnd11 - iStart11)+'ms');

// 倒叙
let arr12 = (new Array(TEST_SIZE)).fill(1);
let target12 = [];
let iStart12 = (new Date()).getTime();
for (let i = arr12.length; i--;) {
target12.push(arr12[i]);
}
let iEnd12 = (new Date()).getTime();
console.log('for-re:' +(iEnd12 - iStart12)+'ms');

// 将取值与判断合并,通过不停的枚举每一项来循环
let arr13 = (new Array(TEST_SIZE)).fill(1);
let target13 = [];
let iStart13 = (new Date()).getTime();
for (let i = 0, a; a = arr13[i]; i++) {
target13.push(a);
}
let iEnd13 = (new Date()).getTime();
console.log('for-a:' +(iEnd13 - iStart13)+'ms');

// forEach
let arr2 = (new Array(TEST_SIZE)).fill(1);
let target2 = [];
let iStart2 = (new Date()).getTime();
arr2.forEach(function(item){
target2.push(item);
});
let iEnd2 = (new Date()).getTime();
console.log('forEach:' +(iEnd2 - iStart2)+'ms');

// map
let arr3 = (new Array(TEST_SIZE)).fill(1);
let target3 = [];
let iStart3 = (new Date()).getTime();
arr3.map(function(item){
target3.push(item);
});
let iEnd3 = (new Date()).getTime();
console.log('map:' +(iEnd3 - iStart3)+'ms');

// while
let arr4 = (new Array(TEST_SIZE)).fill(1);
let target4 = [];
let iStart4 = (new Date()).getTime();
let index = 0;
while(index < arr4.length) {
target4.push(arr4[index]);
index++
}
let iEnd4 = (new Date()).getTime();
console.log('while:' +(iEnd4 - iStart4)+'ms');

// for in
let arr5 = (new Array(TEST_SIZE)).fill(1);
let target5 = [];
let iStart5 = (new Date()).getTime();
for (let obj in arr5) {
target5.push(arr5[obj]);
}
let iEnd5 = (new Date()).getTime();
console.log('forin:' +(iEnd5 - iStart5)+'ms');

结果

测试环境
机器 iMac (Retina 5K, 27-inch, Late 2015) 10.13.6 (17G65)3.2 GHz Intel Core i5
node v8.11.3
chrome 71.0.3578.98(正式版本) (64 位)
firefox 64.0 (64 位)
safair

结果

  • 谷歌浏览器中 ES6+ 的循环语法会普遍比传统的循环语法慢

  • 不管是 for 循环还是 forEach v8 里面都差不多

  • 对于 “枚举” 循环

    数组中应当避免查找空值或者是超出范围的值,这样会导致在原型链中的向上查找,很耗性能。这种循环方式会把所有的元素取出,并不停的迭代下一个,直到出现 undefined 或 null ,这样就出现的向上查找的情景。

  • 对于 提前取数组长度也就是方法二

    实际数组的 length 在每次循环中都会重新读区,并不会提前计算好,而是 v8 引擎最大限度的优化了对象取值的性能。