为什么要做更小的arrays需要更长的时间?

这是一个从1 to n的数组的函数:

  function MakeList(n){ return Array.from(Array(n).keys()).map(function(x){return x+1;}); } 

我计时,所以我可以find这个数组的最快方法:

 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的长度比5长的arrays需要大约20倍?

任何build议最快的方式将不胜感激!

定时一个短的函数调用本身是非常短的,以致在解释器中发生的非常小的变化(启动JIT,编译或优化某些代码,分配一些内存)可能会产生变化,这会影响你logging的时间。 为了解决这个问题,大多数性能testing运行了数千次的迭代,并计算了整个迭代块,以使一次迭代中的微小变化无关紧要。 例如,如果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 

你可以在你最喜欢的浏览器里运行这个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; 

这将在原始数组上创build一个额外的数组条目,然后删除第零个条目以获得基于1的数组,而不是重新创build像您一样的整个新数组。


而且, for循环初始值设定项来说,在Chrome浏览器中显示的速度要快40倍,如下所示:

 function makeList2(n) { let d = new Array(n); for (let i = 1; i <= n; i++) { d[i-1] = i; } return d; }