Javascript 为什么这两个反向循环之间存在性能差异?

Javascript 为什么这两个反向循环之间存在性能差异?,javascript,for-loop,Javascript,For Loop,注意:要在该基准测试套件上运行以下两个测试,请单击Basic reverse for loop和Falsy reverse for loop 下面列出的ops/sec在Chrome32、Win7 64位上 这个环路 for (var i=a.length - 1; i >= 0; i--) { } // 1,161,089 ops/sec 比以前快多了 for (var i=a.length; i--;) { } // 870,837 ops/sec 在Chrome32、Fire

注意:要在该基准测试套件上运行以下两个测试,请单击
Basic reverse for loop
Falsy reverse for loop

下面列出的ops/sec在Chrome32、Win7 64位上


这个环路

for (var i=a.length - 1; i >= 0; i--) { }  // 1,161,089 ops/sec
比以前快多了

for (var i=a.length; i--;) { }  // 870,837 ops/sec
在Chrome32、Firefox27和Opera12&19上。它们在IE(5-11)中大致相同,而falsy循环在Safari Windows(5.1.7)中实际上更快。这似乎与循环条件错误无关——该套件中还有另一个用于比较的基准


“基本”循环比Chrome 32上的“falsy”循环快33%,Win 7 64位。为什么?

第二个循环:
for(var i=a.length;i--;){}
迭代直到
i--
返回false,因为该部分是在循环的条件部分中写入的。
i--
当i等于0时将返回false,因此这两个循环的功能是相同的


但是,第二个循环会导致额外的任务,即将a.length和0之间的每个值转换为布尔值,这比整数比较更耗时。

这一定与Javascript引擎优化有关。如果我在优化Javascript引擎,我会像第一个例子那样寻找代码模式,因为这是编写循环的最规范的方式。一个合理的理由是:在第二个例子中,因为
I--
是一个任意表达式(不是一个裸循环变量),Javascript无法知道任意表达式有多复杂(不进行代码分析);它必须首先计算该表达式,然后再计算结束循环条件,因此您已经失去了一个优化机会。我自己也一直使用第二个版本-我发现它更简洁大多数程序员不期望这种形式,使用它仅仅是为了节省几个字符,这会让下一个程序员在摸索你所做的事情时花费几秒钟的思考时间。不要让未来的代码读者去思考应该是显而易见的代码结构。在Greg Reimer的博客(我基于我的测试)中,他甚至没有包含“基本”版本。JavaScript不会将循环条件(
I--
)强制转换为布尔值。。。它作为一个条件进行计算。此外,我发布的基准测试还包括对(var I=a.length;I-->0;){}的
测试,它的实际性能比falsy版本差一点点(~1%)。