为什么通过一个数组迭代更快,然后转发
给定这个代码
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 > 0
比i < 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++;