javascript array.push(element) vs array[array.length] = element
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16952605/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
array.push(element) vs array[array.length] = element
提问by Tom
I was wondering if there is a reason to choose
我想知道是否有理由选择
array.push(element)
over
超过
array[array.length] = element
or vice-versa.
或相反亦然。
Here's a simple examplewhere I have an array of numbers and I want to make a new array of those numbers multiplied by 2:
这是一个简单的例子,我有一个数字数组,我想创建一个由这些数字乘以 2 的新数组:
var numbers = [5, 7, 20, 3, 13];
var arr1 = [];
var len = numbers.length;
for(var i = 0; i < len; i++){
arr1.push(numbers[i] * 2);
}
alert(arr1);
var arr2 = [];
for(var i = 0; i < len; i++){
arr2[arr2.length] = numbers[i] * 2;
}
alert(arr2);
回答by Joseph Myers
The fastest way to do it with current JavaScript technology, while also using minimal code, is to store the last element first, thereby allocating the full set of array indices, and then counting backwards to 0 while storing the elements, thereby taking advantage of nearby memory storage positions and minimizing cache misses.
使用当前的 JavaScript 技术,同时使用最少的代码,最快的方法是先存储最后一个元素,从而分配完整的数组索引集,然后在存储元素时倒数到 0,从而利用附近的内存存储位置和最小化缓存未命中。
var arr3 = [];
for (var i = len; i>0;){
i--;
arr2[i] = numbers[i] * 2;
}
alert(arr2);
Note that if the number of elements being stored is "big enough" in the view of the JavaScript engine, then the array will be created as a "sparse" array and never converted to a regular flat array.
请注意,如果在 JavaScript 引擎的视图中存储的元素数量“足够大”,那么该数组将被创建为“稀疏”数组,并且永远不会转换为常规平面数组。
Yes, I can back this up. The only problem is that JavaScript optimizers are extremely aggressive in throwing away calculations that aren't used. So in order for the results to be calculated fairly, all the results have to be stored (temporarily). One further optimization that I believed to be obsolete, but actually improves the speed even further is to pre-initialize the array using new Array(*length*)
. That's an old-hat trick that for a while made no difference, but no in the days of extreme JavaScript engine optimizations, it appears to make a difference again.
是的,我可以支持这一点。唯一的问题是 JavaScript 优化器非常积极地丢弃未使用的计算。因此,为了公平计算结果,必须(临时)存储所有结果。我认为已经过时但实际上进一步提高速度的进一步优化是使用new Array(*length*)
. 这是一个老派的把戏,有一段时间没有任何区别,但在极端 JavaScript 引擎优化的日子里,它似乎再次产生了影响。
<script>
function arrayFwd(set) {
var x = [];
for (var i = 0; i<set.length; i++)
x[x.length] = set[i];
return x;
}
function arrayRev(set) {
var x = new Array(set.length);
for (var i = set.length; i>0;) {
i--;
x[i] = set[i];
}
return x;
}
function arrayPush(set) {
var x = [];
for (var i = 0; i<set.length; i++)
x.push(set[i]);
return x;
}
results = []; /* we'll store the results so that
optimizers don't realize the results are not used
and thus skip the function's work completely */
function timer(f, n) {
return function(x) {
var n1 = new Date(), i = n;
do { results.push(f(x)); } while (i-- > 0); // do something here
return (new Date() - n1)/n;
};
}
set = [];
for (i=0; i<4096; i++)
set[i] = (i)*(i+1)/2;
timers = {
forward: timer(arrayFwd, 500),
backward: timer(arrayRev, 500),
push: timer(arrayPush, 500)
};
for (k in timers) {
document.write(k, ' = ', timers[k](set), ' ms<br />');
}
</script>
Opera 12.15:
歌剧 12.15:
forward = 0.12 ms backward = 0.04 ms push = 0.09 ms
向前 = 0.12 毫秒向后 = 0.04 毫秒推动 = 0.09 毫秒
Chrome (latest, v27):
Chrome(最新版本,v27):
forward = 0.07 ms backward = 0.022 ms push = 0.064 ms
向前 = 0.07 毫秒向后 = 0.022 毫秒推动 = 0.064 毫秒
(for comparison, when results are not stored, Chrome produces these numbers: forward = 0.032 ms backward = 0.008 ms push = 0.022 ms
(为了比较,当结果没有被存储时,Chrome 会产生这些数字: forward = 0.032 ms 向后 = 0.008 ms push = 0.022 ms
This is almost four times faster versus doing the array forwards, and almost three times faster versus doing push.)
与向前阵列相比,这几乎快了四倍,与推进相比几乎快了三倍。)
IE 10: forward = 0.028 ms backward = 0.012 ms push = 0.038 ms
IE 10:向前 = 0.028 毫秒向后 = 0.012 毫秒推送 = 0.038 毫秒
Strangely, Firefox still shows push as faster. There must be some code re-writing going on under the hood with Firefox when push is used, because accessing a property and invoking a function are both slower than using an array index in terms of pure, un-enhanced JavaScript performance.
奇怪的是,Firefox 仍然显示推送速度更快。使用 push 时,Firefox 必须重写一些代码,因为就纯的、未增强的 JavaScript 性能而言,访问属性和调用函数都比使用数组索引慢。