我想了解构造数组的性能差异。运行以下程序,我对以下输出感到困惑:
Time for range0: 521
Time for range1: 149
Time for range2: 1848
Time for range3: 8411
Time for range4: 3487
我不明白为什么3需要超过4,而1需要短于2.而且,似乎地图功能效率很低;有什么用?
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);
答案 0 :(得分:1)
我不明白为什么3需要超过4
我也不是。这是一个令人惊讶的结果,鉴于我的肤浅分析和我通过分析代码获得的结果。在运行Google Chrome 50的计算机上,range4
的速度是range3
的两倍。
我必须研究您正在使用的Javascript实现,以便找出发生这种情况的原因。
而1小于2。
range1
执行得更快,因为它使用循环并优化内存分配,而range2
使用函数并执行不必要的内存分配。
另外,地图功能似乎非常低效;有什么用?
map
函数用于根据现有值计算新的Array
。
[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
我的结果反映了我对每项功能表现的期望。
range0
创建Array
并通过循环填充它。它是最简单直接的代码。我认为可以将其理解为基线以进行性能比较。
range1
使用带有长度参数的Array
constructor。这极大地优化了存储元素所需的底层内存分配。由于预先知道元素的确切数量,因此随着元素数量的增加,内存不必realloc
;在实例化Array
时,可以准确地分配存储所有元素所需的确切内存量。
range2
Applies 空参数列表到构造函数,this
设置为数字0
。这在语义上等同于Array()
- 参数列表是使用count
参数创建的,这与函数应用程序的结果无关。实际上,它不必要地浪费时间为空参数列表分配内存。
您可能打算使用call
:
Array.call(null, count)
range3
与range1
类似,但使用带有函数的map
而不是循环。初始内存分配已经过优化,但调用函数count
次的开销可能很大。
此外,map
会生成新的Array
个实例。由于该实例也有count
元素,因此优化 内存分配也是有意义的,但是我不清楚这是否真的发生了。然而,正在进行两次单独的内存分配,而不是range1
中的一次。
range4
结合range2
和range3
的所有低效率。
令人惊讶的是,它的执行速度比计算机上的range3
快。我不明白为什么会发生这种情况。我想有人必须调查你的Javascript特定实现,以便弄明白。