为什么需要更长的时间来制作更小的阵列?

时间:2017-08-09 16:40:15

标签: arrays node.js performance performance-testing

这是从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倍的时间?

任何有关最快方式的建议都将受到赞赏!

1 个答案:

答案 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;
}