【问题标题】:Why is native javascript array forEach method significantly slower than the standard for loop? [duplicate]为什么原生 javascript 数组 forEach 方法明显比标准 for 循环慢? [复制]
【发布时间】:2014-04-05 00:05:36
【问题描述】:

在阅读 Quintus game engine 的源代码时,我发现他们大量使用 for 循环,而不是原生 forEach。

我最初的想法是原生的 forEach 方法会比标准的 for 循环稍微快一些。然而,在用these benchmarks 测试了我的理论之后,for 循环结构似乎要快得多。

四处探查之后,我似乎无法找出引擎盖下发生了什么。有谁知道造成巨大差异的原因吗?

编辑:为了清楚起见,我问的是“为什么”是这种情况。我不是在问“哪个更快”。

【问题讨论】:

  • 一个函数调用涉及不小的开销,.forEach 进行了大量的函数调用。
  • 我添加了一个可能值得探索的新版本:var foo = ""; var fn = 函数(x){ foo += x; }; for(x = 0; x
  • @Pointy 这很奇怪。我原以为引擎会内联这些功能,如下所示:jsperf.com/canvas-pixelwise-manipulation-performance。这里有什么东西可以阻止内联吗?
  • @Pointy,啊……你说得对。我想我现在明白了。内联是对 javascript 代码本身的运行时修改。由于 forEach 是原生的,因此它不会发生在同一级别进行内联。
  • 重复标记没有什么意义。链接的问题问哪个更快,这个问题问为什么。

标签: javascript arrays performance foreach


【解决方案1】:

forEach 在内部包含许多检查,不像简单的循环那么简单。
详情见the Mozilla Javascript reference:

if (!Array.prototype.forEach)
{
  Array.prototype.forEach = function(fun /*, thisArg */)
  {
    "use strict";

    if (this === void 0 || this === null)
      throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun !== "function")
      throw new TypeError();

    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
    for (var i = 0; i < len; i++)
    {
      if (i in t)
        fun.call(thisArg, t[i], i, t);
    }
  };
}

【讨论】:

  • 好点。但是,由于这都是原生的,我希望影响远小于 20 倍以上的性能差异。我在想这可能是这个和这个防止函数内联的某种组合。我会用这些新的观点深入挖掘。
  • @DavidGranado 对此 2017 年的任何更新将不胜感激
【解决方案2】:

感谢您粘贴实现;那里有答案: fun.call 比 fun 慢,i in t 测试很昂贵。

似乎已经非常努力地解决不常见的情况 最终结果对于普通使用来说太昂贵了。

【讨论】:

  • @Nit贴出的代码并不是native forEach方法的实际实现
猜你喜欢
  • 2019-10-28
  • 2017-10-04
  • 2019-03-26
  • 2013-06-02
  • 2014-01-21
  • 1970-01-01
  • 1970-01-01
  • 2011-07-28
相关资源
最近更新 更多