13

我正在阅读 Nicholas Zackas 的高性能 Javascript,他在其中讨论了通过反转 for 循环并最小化其属性查找来优化它。

代替:

for (var i = 0; i < items.length; i++ ) {
  processItems(items[i]);
}

你得到:

for (var i = items.length; i--; ) {
  processItems(items[i]);
}

在撰写本文时,执行时间“比原来快了 50%-60% ”。然而,我创建了一个jsperf,在 Firefox 和 Chrome 中,我注意到优化的 for 循环实际上明显变慢,尤其是在 Firefox 中。

在此处输入图像描述

较新的浏览器是否以不同的方式优化循环?现在编写 for 循环的最有效方法是否只是基本方法?

4

1 回答 1

1

也许您也可以包含测试用例,而不是强制浏览器将答案转换为布尔值?

var i, arr = [...];
for (i = arr.length; i > 0; i -= 1) { arr[i-1] = 1; }

首先,您的循环将 0 强制转换为结束条件,其次,arr[i]其中i = arr.length未定义,这意味着由于隐式类型,Chrome 将在 Chrome 的引擎盖下取消优化循环以访问该数组。

所以现在,就 Chrome 而言,Zakas 的用例中发生了两个大的反优化。

JavaScript 引擎在过去 3 年中确实取得了长足的进步,就他们如何优化幕后事物而言。现在,不再是编写代码来欺骗引擎进行更好的优化(这现在可能与现代浏览器的 JS 编译器中内置的实际优化智能相悖),而更多的是编写常规意义上的优化代码——知道使用哪些数据类型,何时使用等等。

我想你会发现,如果你再次尝试测试,改变我在上面的代码示例中推荐的那两件事,虽然数字可能不完全匹配,但它们会更接近前瞻表现。

于 2013-03-15T18:03:54.957 回答