我很不明白为什么这个测试:
http://jsperf.com/push-method-vs-setting-via-key
显示
a.push(Math.random());
比
慢十倍 a[i] = Math.random();
你能解释为什么会这样吗?什么魔法“推”使它变得如此之慢? (与其他有效的方法相比,这种情况很慢)。
修改
注意:推送测试有偏差。我每次迭代都会增加数组的大小!仔细阅读已接受的答案!
答案 0 :(得分:12)
你能解释为什么会这样吗?
因为您的测试存在缺陷。 push
总是附加到现有的a
数组,使其更大,而第二个测试仅使用前1000个索引。
在这里使用setup
是不够的,您必须在每个for循环之前重置a
数组:http://jsperf.com/push-method-vs-setting-via-key/3。
除此之外,对push
的方法调用可能有一点开销,与使用for循环的索引相比,确定当前数组长度可能需要额外的时间。
通常有no reason not to use push
- 该方法完全适用于该操作,并使某些代码更易于阅读。虽然有些人认为一个版本比另一个版本更快,但两者都在浏览器中同样优化。请参阅Why is array.push sometimes faster than array[n] = value?和Using the push method or .length when adding to array? - 结果差异很大,实际上无关紧要。 使用更好的理解。
答案 1 :(得分:3)
这仅仅是因为谷歌决定在优化数组索引方面投入更多工作,而不是优化Chrome中的push
方法。
如果你看一下测试结果,现在有更多的人尝试过它,你会发现不同浏览器之间的性能差异很大,甚至在同一浏览器的不同版本之间也是如此。
现在浏览器编译Javascript代码,这意味着浏览器将代码转换为运行解释的Javascript更快的代码。编译器对代码的作用决定了不同的执行方式的执行方式。不同的编译器可以更好地优化某些事物,从而提供不同的性能。
答案 2 :(得分:0)
因为.push()是函数调用而另一个是直接赋值。直接分配总是更快。
请记住,在javascript中,数组就像其他所有对象一样。这意味着您可以直接为它们分配属性。
在数组的特殊情况下,它们具有内置的长度属性,可以在幕后进行更新(以及许多其他优化工具,但现在这并不重要。)
在常规对象中,您可以执行此操作,但它不是数组:
var x = {
0: 'a',
1: 'b',
2: 'c'
};
但是,由于数组和散列都是对象,因此这是等效的。
var x = [
'a',
'b',
'c'
];
由于x是第二种情况下的数组,因此长度会自动计算并可用。