Iva*_*hko 6 javascript performance foreach
我注意到,即使对于小型阵列,原生forEach有时也会发生得太慢.看看这个例子:
var a = [], b = [];
a[1234567] = 'foo';
b[10] = 'bar';
a.forEach(function(arg1, arg2) { console.log(arg1, arg2); }); //1
//vs
b.forEach(function(arg1, arg2) { console.log(arg1, arg2); }); //2
Run Code Online (Sandbox Code Playgroud)
在我的Chromium(25.0.1364.160 Ubuntu 12.04)中,第1行和第2行的执行时间是不同的数量级.我知道a的长度等于1234568,而b等于10 等等.但是原生的forEach实现是如此幼稚吗?既一个和b是仅由一个元件构成.如何解释这种行为?
Doo*_*nob 10
那是因为a
长度实际上是1234568,所以你必须循环超过1234568个元素,因为你怎么能确定元素不在那里?
var a = []
a[1234567] = 'foo'
console.log(a.length) // 1234568
Run Code Online (Sandbox Code Playgroud)
因此,它循环超过1234566的无和1 'foo'
,vs数组b
只循环超过9"无"和a 'bar'
.
当foreach
试图阅读时a[0]
,它意识到它不存在,因为a
索引上没有任何东西0
.因此,foreach
想这样:
I'm going to see what a[0] is!
Oh no! It's not there!
I'm going to see what a[1] is!
Oh no! It's not there!
I'm going to see what a[2] is!
Oh no! It's not there!
...
I'm going to see what a[1234567] is!
Yaaaaay! I found it! Now I'll print it!
Run Code Online (Sandbox Code Playgroud)
这就是为什么它需要这么长时间.
forEach
遍历数组的整个长度,在途中跳过不存在的元素.虽然a
并且b
只包含一个元素,但它们length
很大,因此您需要forEach
花费很多时间进行迭代.
毕竟,它在规范中!ES5 15.4.4.18 Array.prototype.forEach的摘录:
6)设k为0.
7)重复,而k <len
为了演示这一点,让我们看看Firefox的SpiderMonkey如何实现这些步骤:
/* Steps 6-7. */
/* Steps a (implicit), and d. */
for (var k = 0; k < len; k++) {
/* Step b */
if (k in O) {
/* Step c. */
callFunction(callbackfn, T, O[k], k, O);
}
}
Run Code Online (Sandbox Code Playgroud)
你可以清楚地看到的循环k
,从0
到len
其谎言在您的性能问题的基础.对于几乎所有的k
,k in O
收益率false
,但你还是觉得一百万次迭代的影响,以及一百万k in O
测试.
作为参考,这里是编写本文时SpiderMonkey和 V8实现的链接.
归档时间: |
|
查看次数: |
2658 次 |
最近记录: |