为什么向后遍历数组的速度比向前快

sam*_*one 53 javascript optimization performance

鉴于此代码:

var arr = [];

for (var i = 0; i < 10000; ++i)
    arr.push(1);
Run Code Online (Sandbox Code Playgroud)

前锋

for (var i = 0; i < arr.length; ++i) {}
Run Code Online (Sandbox Code Playgroud)

向后

for (var i = arr.length - 1; i >= 0; --i) {}
Run Code Online (Sandbox Code Playgroud)

硬编码转发

for (var i = 0; i < 10000; ++i) {}
Run Code Online (Sandbox Code Playgroud)

为什么向后退得这么快?

这是测试:http: //jsperf.com/array-iteration-direction

Ber*_*rgi 83

因为你的前锋条件必须length每次都接收你的数组的属性,而另一个条件只需要检查"大于零",这是一个非常快速的任务.

当你的数组长度在循环期间没有改变,并且你真的看ns-perfomance时,你可以使用

for (var i=0, l=arr.length; i<l; i++)
Run Code Online (Sandbox Code Playgroud)

顺便说一句:for (var i = arr.length; i > 0; --i)你可能会使用for (var i = arr.length; i-- > 0; )从n-1到0的数组,而不是从n到1.

  • 你甚至可以做'(...; i--;)` (4认同)
  • 所以基本上这意味着如果我不更改数组并将 array.length 保留在变量中,那么向后速度 = 向前速度?示例:var length = array.length; for(var i = 0 ; i&lt;length ; i++); (2认同)
  • 快进到2018.看起来现代版本的浏览器即使在每次迭代中访问arr.length时也不会使循环变慢(你的转发案例) (2认同)

rab*_*mar 9

因为在第一种形式中,每次迭代都会访问length数组的属性arr一次,而在第二种形式中,您只执行一次.


tca*_*cak 7

如果你想以相同的速度拥有它们,你可以为前向迭代做到这一点;

for(var i=0, c=arr.length; i<c; i++){
}
Run Code Online (Sandbox Code Playgroud)

因此,您的脚本不需要在everystep上占用数组长度.


小智 5

我对此并不完全确定,但这是我的猜测:

对于以下代码:

for (var i = 0; i < arr.length; ++i) {;
}
Run Code Online (Sandbox Code Playgroud)

在运行期间,每次循环通过后都会进行arr.length计算。当它单独运行时,这可能是微不足道的操作,但对于多个/巨大的阵列可能会产生影响。您可以尝试以下方法:

 var numItems = arr.length;
    for(var i=0; i< numItems; ++i)
    {
    }
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我们仅计算一次数组长度,并以该计算出的数字进行运算,而不是一遍又一遍地执行长度计算。

同样,只是把我的想法放在这里。确实有趣的观察!