忽略所有代码的简洁性和可读性,哪个脚本会更快完成?

这:

for(var i = 0; i < 10; i++){
  --do that thing--
}

或这个:
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--

还是在性能方面都一样?

最佳答案

通过重复“复制和粘贴”循环主体来“展开”循环可以提高或降低的性能。

结果取决于...

  • ...您的JavaScript引擎
  • ...循环主体中的代码
  • ...您的代码记录得很好(没有在开玩笑!)

  • 让我们使用Google流行的V8 JavaScript引擎(Chrome,Node)来分析性能:

    普通循环:
    var count = 0;
    for (var i = 0; i < 10; i++) {
      count += 1;
    }
    

    展开循环:
    var count = 0;
    count += 1;
    count += 1;
    ...
    count += 1;
    

    结果:展开的循环约为快10倍。

    但是,如果我们循环1000次而不是10次呢?然后,展开的循环突然变得比多了,比普通循环慢了10倍!

    如果我们将简单的算术表达式与函数调用交换,该怎么办?

    普通循环:
    function f() {
      return 1;
    }
    
    var count = 0;
    for (var i = 0; i < 10; i++) {
      count += f();
    }
    

    展开循环:
    var count = 0;
    count += f();
    count += f();
    ...
    count += f();
    

    结果:展开循环的速度约为速度的50%。

    但是,如果我们在函数f中添加注释,该怎么办?
    function f() {
      // bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla
      return 1;
    }
    

    突然展开的循环大约 20%!

    为什么?
  • V8在解析正文少于600个字符(包括空格和注释)的函数时会自动内联代码。
  • 当函数在很长的循环中“卡住”时,
  • V8执行on-stack-replacement

  • 关于最后一个示例:通过添加一个大于600个字符的长注释,我们防止了V8在解析过程中内联函数f,而是依赖于运行时优化功能(例如“堆栈替换”),该功能针对整个函数和循环,但不针对手动重复的代码。

    如您所见,很难预测这种微观“优化”的结果。因此最好不要这样做-除非您针对特定JS引擎的特定版本。

    有关性能分析,请参见https://jsfiddle.net/Lj9v7c2m/-根据您的计算机/浏览器/版本,您可能会获得不同的结果。

    关于JavaScript-循环是否比逐行逐行编写要快?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38111355/

    10-16 22:03