问题描述
我正在考虑使用本机方法创建包含默认值的数组的方法,结果是
I was considering ways to create arrays containing a default value using native methods and ended up with
function pushMap(length, fill){
var a = [], b = [];
a.length = length;
b.push.apply(b,a);
return b.map(function(){return fill;});
}
期望它比 while 循环慢 2 或 3 倍,因为本机方法必须循环两次而 while 只循环一次,所以我比较了它jsperf反对
Expecting it to be 2 or 3 times slower than a while loop, as the native methods have to loop twice whereas while loops only once, so I compared it on jsperf against
function whileLengthNew(len, val) {
var rv = new Array(len);
while (--len >= 0) {
rv[len] = val;
}
return rv;
}
它实际上慢了 18 到 27 倍(在 Ubuntu 上用 Google Chrome 测试,欢迎浏览器/操作系统).
and it is actually 18 to 27 times slower (tested with Google Chrome on Ubuntu, browsers/OSs welcome).
发生了什么导致如此大的差异?
What is happening that causes such a big difference?
推荐答案
我认为这是由于两个主要因素:
I would expect that this is due to two major factors:
内存分配 --
whileLengthNew
先创建一个正确大小的数组,然后对其进行操作,pushMap
一次创建一个元素的最终数组使用map
.这可能会导致多次分配,尤其是在源数组很大的情况下.(创建初始a
和b
数组的方式基本上无关紧要,因为map
正在构建一个新数组,无论如何都要返回——它实际上并没有改变b
)
Memory allocation --
whileLengthNew
creates an array of the correct size first, and then operates on it,pushMap
creates the final array one element at a time withmap
. This may cause multiple allocations, especially if the source array is large. (The way that you create the initiala
andb
arrays is basically irrelevant, sincemap
is building up a new array to return anyway -- it doesn't actually change anything inb
)
函数调用开销 -- 在调用 map
时,您正在为数组的每个元素调用一个函数.这涉及相当多的开销;设置激活记录和作用域链,堆栈操作,并将返回值传回.-- 所有这些都是为了访问函数内的常量变量.最重要的是,您已经设置了一个闭包,因此即使访问fill
变量也比whileLengthNew
版本中的要慢.
Function call overhead -- in your call to map
, you are calling a function for every element of the array. This involves quite a lot of overhead; setting up activation records and scope chains, stack manipulation, and passing the return value back. -- all of this to access a variable which is constant within the function. On top of that, you have set up a closure, so even accessing the fill
variable is slower than it is in the whileLengthNew
version.
这篇关于为什么使用 while 循环填充新数组的速度如此之快?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!