http://jsperf.com/testing-foreach-vs-for-loop
据我了解,测试用例2应该比测试用例1运行更慢-- 我想看看它慢多少。但让我惊讶的是,它运行得更快了!
这是怎么回事?背后的优化原因?还是 .forEach 更简洁,更快?
在 Windows Server 2008 R2 / 7 64-bit 上使用 Chrome 18.0.1025.142 32-bit 进行测试。
http://jsperf.com/testing-foreach-vs-for-loop
据我了解,测试用例2应该比测试用例1运行更慢-- 我想看看它慢多少。但让我惊讶的是,它运行得更快了!
这是怎么回事?背后的优化原因?还是 .forEach 更简洁,更快?
在 Windows Server 2008 R2 / 7 64-bit 上使用 Chrome 18.0.1025.142 32-bit 进行测试。
+=1
而不是++
实际上没有任何变化。 - kirilloid更新:
很多旧技巧在老浏览器中的解释JS非常好。
在任何现代JS实现中,包括所有现代浏览器、Node和最新的移动Webviews,内联函数实际上可以被JIT(JS编译器)缓存,使得forEach成为数组迭代的更快选项。以前情况相反,仅重复调用函数需要建立/拆除过程,这可能会严重降低非平凡循环的性能。
为了获得最佳性能,如果不必要,我建议避免引用任何未传递为参数或在函数本身中定义的内容。我不确定这是否有影响,但我可以理解为什么会有影响。
涉及任何查询过程的Getter值,例如数组长度或DOM节点属性,也可能最好缓存到变量中。
但除此之外,我会尝试让工作避免的基本原则指导您的性能努力。预先计算不需要在循环中重新计算的事物,或将查询选择器结果缓存到var而不是反复在DOM中搜寻,这些都是很好的例子。试图过分利用JIT行为可能会变得相当深奥,并且不太可能随着时间的推移或跨越所有JITs而持续。
旧答案:
好的,忘记长篇大论。要点如下:
var i = someArray.length; //length is cached
someArray.reverse(); //include this only if iterating in 0-(length-1) order is important
while(i--){
//run a test statement on someArray[i];
}
长度已缓存并立即转换为索引
在 JavaScript 中向后迭代的好处是避免使用具有两个操作数的逻辑运算符。在这种情况下,我们只是评估一个数字。它是真的还是零和假。
我也觉得它很优美。
在每次迭代中从array
读取length
可能会很慢,但是forEach
通常更慢,因为在js中函数调用不是廉价操作。
附注:forEach
在FF10上比较慢14%。
在 Opera 中对我来说它们大致相同。需要注意的是,您在 for() 中的条件是 array.length。如果您将数组的长度缓存到变量中,然后循环,您应该会看到更好的性能。
也许 for() 循环较慢是因为每次迭代都会应用 'array.length' 来获取数组的长度。
尝试:
var nri = array.length;
for( var i = 0; i < nri; i++ ){
// ...
}
forEach
可能具有一些本地优化,或者其他什么东西。 - gen_Ericarray[i]
的值。请修改代码。 - huysentruitw