为什么通过一个数组迭代更快,然后转发

给定这个代码

var arr = []; for (var i = 0; i < 10000; ++i) { arr.push(1); } 

前锋

 for (var i = 0; i < arr.length; ++i) {; } 

向后

 for (var i = arr.length - 1; i >= 0; --i) {; } 

硬编码转发

 for (var i = 0; i < 10000; ++i) {; } 

为什么backwords如此之快?

这是testinghttp://jsperf.com/array-iteration-direction

因为你的转发条件每次都要接收数组的length属性,而另一个条件只需要检查“大于零”,这是一个非常快的任务。

当你的数组长度在循环过程中没有改变时,你真的看看ns-perfomance,你可以使用

 for (var i=0, l=arr.length; i<l; i++) 

顺便说一句:代替for (var i = arr.length; i > 0; --i)你可以使用for (var i = arr.length; i-- > 0; ) ,它真的从n-1到0,而不是从n到1。

因为在第一种forms中,每次迭代都要访问数组arr的属性length ,而在第二种情况下,只能执行一次。

如果你想让它们以相同的速度进行,你可以做前向迭代;

 for(var i=0, c=arr.length; i<c; i++){ } 

所以,你的脚本永远不需要花费很长的时间。

我不完全确定这一点,但这是我的猜测:

对于下面的代码:

 for (var i = 0; i < arr.length; ++i) {; } 

在运行期间,每个循环遍历后都有一个arr.length计算。 当它独立时,这可能是微不足道的操作,但对于多个/巨大的arrays可能会有影响。 你可以尝试以下几点:

  var numItems = arr.length; for(var i=0; i< numItems; ++i) { } 

在上面的代码中,我们只计算一次数组的长度,并且使用该计算的数字进行操作,而不是一次又一次地执行长度计算。

再次,把我的想法放在这里。 有趣的观察确实!

i > 0i < arr.length更快并且在循环的每次迭代中发生。

你可以用这个来减轻不同之处:

 for (var i = 0, len = arr.length; i < len; ++i) {; } 

这还不如倒退的项目快,但比你的前锋选项快。

如下所示,它将以相同的方式执行。 因为arr.length在每次迭代中arr.length需要时间。

 int len = arr.length; 

前锋

 for (var i = 0; i < len; ++i) { } 

落后

 for (var i = len; i > 0; --i) { } 

这些同样好:

 var arr= [], L= 10000; while(L>-1) arr[L]= L--; 

要么

 var arr= [], i= 0; while(i<10001) arr[i]=i++;