【问题标题】:How well does v8 optimise nested functions?v8 对嵌套函数的优化如何?
【发布时间】:2023-04-07 12:38:01
【问题描述】:

有时我会看到如下代码:

var doSomething = function(object){
    var results = []
    var doSomethingElse = function(object){
        ...
    }
    results.push(doSomethingElse(...))
    return results
}

这样组织是因为doSomethingElse 只在doSomething 中有意义。性能是可以接受的,所以这只是一个好奇:v8 对嵌套函数的优化如何? 每次调用 doSomething() 时都会实例化一个新的 doSomethingElse() 副本吗?

【问题讨论】:

    标签: javascript node.js optimization v8


    【解决方案1】:

    我不了解 V8 的内部结构,但我认为闭包应该得到很好的优化。但是要回答您问题的另一部分:是的,每个doSomething 调用都会创建一个新的doSomethingElse。这是从语言的角度讲的。从技术上讲,智能 JIT 可能已经对此进行了优化。

    如果您担心这一点,您可以通过在自调用函数中定义 doSomethingElse 来保证它被创建一次:

    var doSomething = (function() {
      var doSomethingElse = function(object){ // only defined once
          ...
      };
    
      return function(object){ // the actual doSomething function
          var results = [];
          results.push(doSomethingElse(...));
          return results;
      };
    }());
    

    您只需要记住,这将在所有 doSomething 调用中持续存在 doSomethingElse。所以如果你做任何有状态的事情,你可能会看到一些意想不到的行为。

    【讨论】:

    • 这不是闭包:doSomething() 中没有变量被关闭,它是一个值的直接返回。垃圾收集器可以在函数返回后从doSomething() 的范围内删除所有内容。
    • @mikemaccana 是的,你原来的例子 can 是一个闭包,但是因为你的嵌套函数只是接收一个 object 来专门处理而不是使用封闭的变量,改用这种非闭包优化是有效的。
    【解决方案2】:

    我不知道它的优化程度如何,我认为你永远不会得到这样的信息,那种问题太宽泛了,我知道是因为我以前问过这些问题,答案总是“试试看,配置文件,看看”。

    再一次,我不会回答这么说。

    我发现有 2 个来源推荐 AGAINST 使用它们,因为它们为引擎添加了另一个步骤,因为它每次都需要创建函数,并向作用域链添加一个级别。

    这里的确切原因和测试:

    http://code.tutsplus.com/tutorials/stop-nesting-functions-but-not-all-of-them--net-22315

    https://developers.google.com/speed/articles/optimizing-javascript

    这可能应该在评论中,但我还不能评论。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-09
      • 2015-10-24
      • 1970-01-01
      相关资源
      最近更新 更多