【问题标题】:Is it good practice to define array's length before the loop? [duplicate]在循环之前定义数组的长度是一种好习惯吗? [复制]
【发布时间】:2023-03-17 14:57:01
【问题描述】:

我在 Ember.js 中看到了这个 sn-p:

  for (var i=0, l=deps.length; i<l; i++) {
    if (deps[i] === 'exports') {
      reified.push(exports = {});
    } else {
      reified.push(requireModule(resolve(deps[i])));
    }
  }

请看var i=0, l=deps.length; i&lt;l; i++deps的长度是在循环之前定义的。我想知道为什么他们必须这样做而不是只使用var i=0; i&lt;deps.length; i++。我想这可能是一个“性能技巧”,所以我决定在 jsperf 上做一个测试:

http://jsperf.com/predefined-length-vs-inline-defined-length

结果显示第二个更快。所以他们使用第一个肯定有另一个原因。

有人知道吗?非常感谢。

【问题讨论】:

  • 您是否意识到差别不大。一个设置变量,一个不设置。较旧的浏览器需要存储长度以使其运行得更快。现代浏览器,没有区别。
  • 这是因为每次迭代都会查找 for 循环中的语句,因此您可以节省一点缓存长度而不是每次迭代都查找它,但大多数情况下差异不是很明显,所以没关系。如前所述,较新的浏览器已经在内部对此进行了优化。
  • 需要注意的是,如果顺序无关紧要,通常只是反向迭代更容易更快for (var i=deps.length; i--;) ...

标签: javascript arrays performance loops


【解决方案1】:

这与其说是一个小的性能优化,不如说是一个好的做法。在非常大的阵列中,它将产生显着的性能改进。这样做的原因是它“缓存”了数组、NodeList 等的长度值,因此在循环的退出条件下,您不必每次都重新访问该属性,因为它存储在变量中.

与任何代码一样,性能提升各不相同,可能更快或更慢,具体取决于浏览器。

【讨论】:

    【解决方案2】:

    这是一个棘手的问题,因为我们都认为计算长度会更好。但在任何一种情况下,实际计算长度只会发生一次。但是在第一个中,除了迭代器“i”之外,您还声明了一个变量。所以VM需要为其分配一个临时空间,直到循环结束;这就是原因首先是最慢的。

    希望对你有所帮助。

    【讨论】:

    • 循环的条件部分需要在每次循环体执行之前进行评估。所以i &lt; l 总是只做两个变量之间的比较,而i &lt; deps.length 理论上总是需要访问deps 的属性length(而且速度更慢)。 JS 引擎可能足够智能,可以将i &lt; deps.length 简化为i &lt; l,这更有可能是两个测试没有区别的原因。 3.323.49 不能被视为差异,尤其是当你重复它时它会翻转。
    猜你喜欢
    • 2014-11-05
    • 2017-02-21
    • 2018-11-17
    • 1970-01-01
    • 2014-10-06
    • 1970-01-01
    • 2017-07-15
    • 1970-01-01
    • 2015-01-08
    相关资源
    最近更新 更多