鉴于此代码:
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) {}
为什么向后的速度要快得多?
鉴于此代码:
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) {}
为什么向后的速度要快得多?
因为您的转发条件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; )
which 真正从 n-1 到 0,而不是从 n 到 1 遍历您的数组。
因为在第一种形式中,您每次迭代都会访问一次length
数组的属性arr
,而在第二种形式中,您只访问一次。
如果您想让它们以相同的速度运行,则可以为前向迭代执行此操作;
for(var i=0, c=arr.length; i<c; i++){
}
因此,您的脚本不需要在每一步都占用数组的长度。
我对此并不完全确定,但这是我的猜测:
对于以下代码:
for (var i = 0; i < arr.length; ++i) {;
}
在运行时,每次循环通过后都会进行 arr.length 计算。这在单独使用时可能是微不足道的操作,但在涉及多个/大型阵列时可能会产生影响。您可以尝试以下操作:
var numItems = arr.length;
for(var i=0; i< numItems; ++i)
{
}
在上面的代码中,我们只计算一次数组长度,并使用计算出的数字进行操作,而不是一遍又一遍地执行长度计算。
再次,只是把我的想法放在这里。确实有趣的观察!
i > 0
比i < arr.length
循环的每次迭代都快并且正在发生。
您可以通过以下方式减轻差异:
for (var i = 0, len = arr.length; i < len; ++i) {;
}
这仍然不如向后项目快,但比向前选项快。