【问题标题】:Why is there a performance difference between these two reverse loops?为什么这两个反向循环之间存在性能差异?
【发布时间】:2014-01-12 18:26:39
【问题描述】:

Benchmarks

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

下面列出的 ops/sec 适用于 Chrome 32、Win 7 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

在 Chrome 32、Firefox 27 和 Opera 12 和 19 上。它们在 IE (5 - 11) 中大致相等,而在 Safari Windows (5.1.7) 中虚假循环实际上更快。这似乎与循环条件是虚假的没有任何关系 - 该套件中有另一个基准可以进行比较。

“基本”循环比 Chrome 32、Win 7 64 位上的“虚假”循环快约 33%。为什么?

【问题讨论】:

  • 这肯定和Javascript引擎优化有关。如果我正在优化一个 Javascript 引擎,我会像第一个示例一样寻找代码模式,因为这是编写循环的最规范的方式。
  • 一个合理的原因:在第二个例子中,因为I-- 是一个任意表达式(不是一个裸循环变量),Javascript 无法知道该任意表达式有多复杂(不做一些代码分析);它必须先评估该表达式首先,然后再评估结束循环条件,因此您已经失去了优化机会。
  • 我自己一直使用第二个版本 - 我觉得它更简洁
  • 大多数程序员并不期望这种形式,并且使用它来节省几个字符会花费下一个程序员几秒钟的思考时间,同时他们会摸索你所做的事情。不要让您的代码的未来读者考虑应该显而易见的代码结构。
  • 在 Greg Reimer 的博客(我的测试依据)中,他甚至没有包含“基本”版本。

标签: javascript for-loop


【解决方案1】:

第二个循环:for (var i=a.length; i--;) { } 迭代直到 i-- 返回 false,因为该部分被写入循环的条件部分。 i-- 在 i 等于 0 时会返回 false,所以两个循环的功能是一样的。

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

【讨论】:

  • JavaScript 不会将循环条件 (i--) 转换为布尔值...它被评估为 falsy 条件。此外,我发布的基准测试包括对for (var i=a.length; i-->0;) { } 的测试,它实际上比虚假版本差一点点(~1%)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-03
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-15
  • 1970-01-01
相关资源
最近更新 更多