现代JavaScript JITers需要循环中的数组长度缓存吗?

Dom*_*nic 13 javascript optimization jit loops

我发现在循环中缓存数组length属性的做法for非常令人反感.如,

for (var i = 0, l = myArray.length; i < l; ++i) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

至少在我看来,与直截了当相比,这对可读性造成了很大伤害

for (var i = 0; i < myArray.length; ++i) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

(更不用说由于词法范围和提升的性质,它会将另一个变量泄漏到周围的函数中.)

我希望能够告诉任何做这件事的人"不要打扰;现代的JS JITers会优化这个技巧." 显然这不是一个微不足道的优化,因为你可以在迭代过程中修改数组,但我会认为考虑到JITers和他们的运行时分析技巧所听到的所有疯狂的东西,他们已经得到了这个现在.

任何人都有这样或那样的证据吗?

是的,我也希望说"这是微观优化就足够了;在你描述之前不要这样做." 但并不是每个人都会听到这种理由,特别是当它成为缓存长度的习惯时,它们最终会自动地这样做,几乎就像一种风格选择.

Tim*_*own 12

这取决于一些事情:

  • 您是否已经证明您的代码花费了大量时间循环
  • 您是否完全支持最慢的浏览器是否受益于数组长度缓存
  • 无论您是否或处理代码的人都发现数组长度缓存难以阅读

从我看到的基准测试(例如,这里这里)来看,IE <9中的性能(通常是你必须处理的最慢的浏览器)可以从缓存数组长度中受益,所以它可能值得做.对于它的价值,我有一个缓存数组长度的长期习惯,因此很容易阅读.还有其他循环优化可以产生影响,例如倒计时而不是倒计时.

以下是来自JSMentors邮件列表的相关讨论:http://groups.google.com/group/jsmentors/browse_thread/thread/526c1ddeccfe90f0


Jua*_*des 5

我的测试显示所有主要的新浏览器都缓存了数组的长度属性.你不需要自己缓存它,除非你担心IE6或7,我不记得确切.但是,从那时起我就一直在使用另一种迭代方式,因为它给了我另一个好处,我将在下面的例子中描述:

var arr = ["Hello", "there", "sup"];
for (var i=0, str; str = arr[i]; i++) {
  // I already have the item being iterated in the loop as 'str'
  alert(str);
}
Run Code Online (Sandbox Code Playgroud)

如果允许数组包含'falsy'值,则必须意识到此迭代样式会停止,因此在这种情况下不能使用此样式.

  • @Tim是否有缩短记谱法的任何好处?这是相同数量的操作,但不太清楚.但是你对这个方法与那些期望有假类型的数组不兼容是正确的.像所有工具一样,似乎只应在适当的时候使用它. (3认同)