【问题标题】:forEach function much faster than equivalent for loopforEach 函数比等效的 for 循环快得多
【发布时间】:2015-06-26 12:35:20
【问题描述】:

在我正在构建的 Angular 应用程序中,我有两段代码在每次刷新时触发。它们都做同样的事情,但更快的是数组 forEach 函数,我认为它应该稍微

如果您发现错误,那太好了!但是为什么 foreach 循环会快得多。它们紧随其后,如果我改变顺序,也没有什么不同。

第一个更快。使用performance.now() 时平均大约需要 5 毫秒。

var start = performance.now();
start = performance.now();
$scope.config.formTables.forEach(function (e, i, a) {
    ['tbody', 'thead', 'tfoot'].forEach(function (f, j) {
        if (!$scope.config[e][f]) return;
        $scope.config[e][f].forEach(function (g, k) {
            if(isFunction(g.calculated || {})) g.calculated.apply(g);
        })
    })
});
console.log(performance.now() - start);  

现在是较慢的,我认为应该更快。这需要 100-200 毫秒。

start = performance.now();
var i,j,k,e,f,g;
for(i = 0; i < $scope.config.formTables.length; i++){
    e = $scope.config[$scope.config.formTables[i]];
    if(e.thead)
    for(j = 0; j < e.thead.length; j++){
        f = e.thead;
        for(k = 0; k < f.length; k++){
            //g = f[j];
            if(isFunction(f[j].calculated || {})) f[j].calculated.apply(f[j]);
        }
    }
    if(e.tfoot)
    for(j = 0; j < e.tfoot.length; j++){
        f = e.tfoot;
        for(k = 0; k < f.length; k++){
            //g = f[j];
            if(isFunction(f[j].calculated || {})) f[j].calculated.apply(f[j]);
        }
    }
    if(e.tbody)
    for(j = 0; j < e.tbody.length; j++){
        f = e.tbody;
        for(k = 0; k < f.length; k++){
            //g = f[j];
            if(isFunction(f[j].calculated || {})) f[j].calculated.apply(f[j]);
        }
    }
}
console.log(performance.now() - start);

【问题讨论】:

  • 请使用更具描述性的变量名,这段代码很难阅读。 (当我试图找出config[e][f] 是否与e.tfoot[j] 相同时,我停了下来。)
  • jsperf 可用时
  • 您的两个代码示例看起来不像在做同样的事情。也许他们是,但它隐藏在我们看不到的数据背后。

标签: javascript angularjs performance for-loop foreach


【解决方案1】:

不,它们不等价,因为这一点:

for(j = 0; j < e.thead.length; j++){
    f = e.thead;
    for(k = 0; k < f.length; k++){
        //g = f[j];
        if(isFunction(f[j].calculated || {})) f[j].calculated.apply(f[j]);
    }
}

在这里,您基本上是在重复同一件事两次,嵌套会降低性能。只需省略其中一个循环 - 您可能还会注意到您从未在循环主体中使用 k

应该只是

if(e.thead) {
    f = e.thead;
    for(k = 0; k < f.length; k++){
        //g = f[j];
        if(isFunction(f[k].calculated || {})) f[k].calculated.apply(f[k]);
    }
}

请注意f == "thead"j 从未在您的forEach 版本中使用。

您确实应该使用更具描述性的变量名称,这样这样的事情就会更加明显。 ef 在两个版本中也不是同义词。

【讨论】:

  • 哎呀,你是对的。那会有很大的不同。他可以通过去掉.apply() 并模拟forEach() 来稍微缩短代码。
  • @squint:由于我不知道他的apply到底是什么,所以我不敢碰它。但这种说法确实看起来很可疑。
  • 是的,别管它可能是个好主意。由于isFunction() 调用,很可能是Function#apply,但谁知道呢。我一直在试图找出他的变量,以至于我完全错过了冗余循环。不错!
  • 确实是Function#apply。我只是在函数上设置this,但我可以将它作为变量传递。只是好奇——这就是这样做的方法吗?
  • @ArlenBeiler:您没有将this 设置为函数,而是设置为f[k] 对象。一个简单的方法调用f[k].calculated() 也会做同样的事情。
猜你喜欢
  • 2022-01-04
  • 2014-01-21
  • 2022-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-02
  • 2012-04-26
相关资源
最近更新 更多