我想了解构造数组的性能差异。运行以下程序,我对下面的输出感到困惑:
Time for range0: 521
Time for range1: 149
Time for range2: 1848
Time for range3: 8411
Time for range4: 3487
我不明白为什么 3 比 4 需要更长的时间,而 1 比 2 更短。而且,map 函数似乎效率很低;它有什么用?
<小时/>function range0(start, count) {
var arr = [];
for (var i = 0; i < count; i++) {
arr.push(start + i);
}
return arr;
}
function range1(start, count) {
var arr = new Array(count);
for (var i = 0; i < count; i++) {
arr[i] = start + i;
}
return arr;
}
function range2(start, count) {
var arr = Array.apply(0, Array(count));
for (var i = 0; i < count; i++) {
arr[i] = start + i;
}
return arr;
}
function range3(start, count) {
var arr = new Array(count);
return arr.map(function(element, index) {
return index + start;
});
}
function range4(start, count) {
var arr = Array.apply(0, Array(count));
return arr.map(function(element, index) {
return index + start;
});
}
function profile(range) {
var iterations = 100000,
start = 0, count = 1000,
startTime, endTime, finalTime;
startTime = performance.now();
for (var i = 0; i < iterations; ++i) {
range(start, count);
}
endTime = performance.now();
finalTime = (endTime - startTime);
console.log(range.name + ': ' + finalTime + ' ms');
}
[range0, range1, range2, range3, range4].forEach(profile);
最佳答案
I don't understand why 3 takes longer than 4
我也没有。考虑到我的肤浅分析和通过分析代码获得的结果,这是一个令人惊讶的结果。在我运行 Google Chrome 50 的计算机上,range4
的速度是 range3
的两倍。
我必须研究您正在使用的 Javascript 实现才能找出发生这种情况的原因。
while 1 takes shorter than 2.
range1
执行速度更快,因为它使用循环并优化内存分配,而 range2
使用函数并执行不必要的内存分配。
Also, seems the map function is very inefficient; what is the use of it?
map
函数用于根据现有数组的值计算新的数组
。
[1, 2, 3, 4, 5].map(number => number * number);
// [1, 4, 9, 16, 25]
<小时/>
在我的计算机上
Time for range0: 783
Time for range1: 287
Time for range2: 10541
Time for range3: 14981
Time for range4: 28243
我的结果反射(reflect)了我对每个功能的性能的期望。
各个功能浅析
范围0
创建
Array
并通过循环填充它。这是最简单、最直接的代码。我想它可以被理解为性能比较的基线。范围1
使用
Array
constructor带长度参数。这极大地优化了存储元素所需的底层内存分配。由于元素的确切数量事先已知,因此内存不必是realloc
随着元素数量的增加而增加;当Array
时,存储所有元素所需的确切内存量可以被分配一次。已实例化。范围2
Applies构造函数的空参数列表,其中
this
设置为数字0
。这在语义上等同于Array()
– 事实上,参数列表是使用count
参数创建的,这对函数应用程序的结果没有影响。事实上,它不必要地浪费时间为空参数列表分配内存。您可能想使用
call
:Array.call(null, count)
范围3
与
range1
类似,但使用map
用函数而不是循环。初始内存分配已优化,但调用函数count
次的开销可能会很大。此外,
map
生成一个新的Array
实例。由于该实例也有count
元素,因此优化该内存分配也是有意义的,但我不清楚这是否真的发生。尽管如此,还是发生了两次单独的内存分配,而不是像range1
中那样只进行一次。范围4
结合了
range2
和range3
的所有低效之处。令人惊讶的是,它在计算机上的执行速度比
range3
还要快。我不清楚为什么会发生这种情况。我想人们必须研究你的 Javascript 特定实现才能弄清楚。
关于javascript - 创建 Javascript 数组的不同方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37557135/