Javascript 为什么向后遍历数组比向前遍历更快

Javascript 为什么向后遍历数组比向前遍历更快,javascript,performance,optimization,Javascript,Performance,Optimization,鉴于此代码: var arr = []; for (var i = 0; i < 10000; ++i) arr.push(1); 硬编码转发 for (var i = 0; i < 10000; ++i) {} for (var i = 0; i < len; ++i) { } for (var i = len; i > 0; --i) { } (var i=0;i0比i=0)arr[L]=L;@samccone-您看到了什么结果(哪个浏览器中的哪个测

鉴于此代码:

var arr = [];

for (var i = 0; i < 10000; ++i)
    arr.push(1);
硬编码转发

for (var i = 0; i < 10000; ++i) {}
for (var i = 0; i < len; ++i) {
}
for (var i = len; i > 0; --i) {
}
(var i=0;i<10000;++i){ 为什么后退速度要快得多

以下是测试:
因为在第一种形式中,每次迭代都要访问数组
arr
的属性
length
,而在第二种形式中,只访问一次。

i>0
i
快,并且在循环的每次迭代中都会发生

您可以通过以下方式缓解差异:

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

这仍然不如向后项快,但比向前选项快。

如果您想让它们保持相同的速度,您可以在向前迭代中这样做

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

对于(var i=0,c=arr.length;i而言,这些都同样好:

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

var-arr=[],i=0;

虽然(我对此我并不完全确定,但我猜:

对于以下代码:

for (var i = 0; i < arr.length; ++i) {;
}
for(var i=0;i
在运行时,每次循环通过后都会进行arr.length计算。这在单独运行时可能是一个微不足道的操作,但在涉及多个/大型阵列时可能会产生影响。您可以尝试以下操作:

 var numItems = arr.length;
    for(var i=0; i< numItems; ++i)
    {
    }
var numItems=arr.length;
对于(变量i=0;i
在上面的代码中,我们只计算一次数组长度,并使用计算出的数字进行操作,而不是反复执行长度计算


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

像下面这样做,它将以同样的方式执行。因为
arr.length
在向前的每次迭代中都需要时间

int len = arr.length;
向前

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

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

当您的数组长度在循环过程中没有改变,并且您真正关注ns性能时,您可以使用

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

for(var i=0,l=arr.length;i0;--i)
您可以使用
for(var i=arr.length;i-->0;)
它实际上是从n-1到0,而不是从n到1在数组中运行的。

看看硬编码测试…使用您的逻辑,它应该更快不?啊哈…有趣的是,您的方法现在以最快的迭代速度为冠向后的情况是不对的。我所做的是(I=len;--I>=0;){
for(让I=arr.length;I-->0;){
它应该是
而(-L>=0)arr[L]=L;
@samccone-您看到了什么结果(哪个浏览器中的哪个测试)?我发现缓存长度总是至少一样快,而且通常更快。好吧,你是对的…看起来它确实是一个混合的结果包,但是缓存确实有帮助…感谢XDYep,这就是我为优化函数所做的。请注意,如果数组是可变的(通常不是可变的),这可能会跳过一两个资源。例如,如果在循环本身正在添加或删除的元素之间循环,则此操作将不起作用。您甚至可以对(…;i-->)执行
因此,基本上这意味着如果我不更改数组,并且在变量中保留array.length,那么向后速度=向前速度?例如:var length=array.length;for(var I=0;iafaik,
i0
,但是是的,它们相当相等(比未缓存的长度快):-然而,一些引擎确实识别并优化了其中的一些案例,并将其提前到2018年。看起来,即使在每次迭代中访问arr.length时,浏览器的现代版本也不会使循环变慢(转发案例)请注意,您的倒排大小写应该从
arr.length-1
开始,并使
i>=0
而不是
i>0
。标题具有误导性。在高级浏览器中直接使用arr.length的速度不再较慢。可能重复