这是从1 to n
生成数组的函数:
function MakeList(n){
return Array.from(Array(n).keys()).map(function(x){return x+1;});
}
我计时了,所以我可以找到制作这个阵列的最快方法:
console.log(n);
console.time("MakeList");
var ar = MakeList(n);
console.timeEnd("MakeList");
但输出是如此的!:
1
MakeList: 0.897ms
2
MakeList: 0.135ms
5
MakeList: 0.048ms
为什么制作长度为1的阵列需要大约20倍的时间?
任何有关最快方式的建议都将受到赞赏!
答案 0 :(得分:0)
单独调用一个短函数调用是如此之短,以至于解释器中正在发生的其他事情的非常小的变化(启动JIT,编译或优化某些代码,分配一些内存)可能会产生影响你记录的时间。为了解决这个问题,大多数性能测试运行数千次迭代并对整个迭代块进行计时,以使一次迭代中的小变化无关紧要。例如,如果您的函数在jsperf中的值为1,2,5和10,每次执行数千次迭代,那么您将获得Chrome,Firefox和Edge中的预期完成顺序。以下是Chrome的数字(更高的数字更快):
makeList(1) 2,470,356 ops/sec
makeList(2) 1,861,029 ops/sec
makeList(5) 992,583 ops/sec
makeList(10) 626,572 ops/sec
您可以在this jsperf。
中自己喜欢的浏览器中自行运行由于您对速度感兴趣,您可以立即改进并通过更改此消除.map()
:
return Array.from(Array(n).keys()).map(function(x){return x+1;});
到此:
let d = Array.from(Array(n + 1).keys());
d.shift();
return d;
这会在原始数组上创建一个额外的数组条目,然后删除第0个条目以获得基于1的数组,而不是像您一样重新创建一个全新的数组。
而且,普通的for
循环初始化程序在Chrome中的速度提高了40倍,如this jsperf所示:
function makeList2(n) {
let d = new Array(n);
for (let i = 1; i <= n; i++) {
d[i-1] = i;
}
return d;
}