javascript - Javascript (V8) 是否优化未使用的返回值

标签 javascript v8

假设我们有一个像这样的函数:

function foo() {
  // do some work...
  return () => {}; // foo returns a function
}

客户端代码可以在两种情况下使用 foo:

  1. 使用函数的结果
const result = foo();
// some code that uses result...
  • 忽略函数的结果
  • foo();
    

    我想知道运行时(我不想引用语言本身,因为这可能依赖于实现)是否会优化第一种情况,所以我不必像这样自己做:

    function foo(needTheResultValue = false) {
      // do some work...
      if (needTheResultValue) return () => {};
      // nothing is returned if the caller didn't ask for it
    }
    

    最佳答案

    V8 开发人员在这里。简短的回答是“这取决于情况,不用担心”。

    一般来说,V8(以及据我所知的其他引擎)会针对每个功能进行优化。所以,在你的例子中,如果foo被优化了,它不知道它的返回值会被使用还是被忽略,所以它不能优化掉它。

    异常(exception)情况是内联:优化编译器能够在优化调用函数时内联被调用的函数,例如在此示例中:

    function foo() {
      // Do some FOO work...
      return {};
    }
    function bar() {
      foo();
      // Do some BAR work...
    }
    

    何时 foo被优化后,它将(继续)返回一个新分配的空对象,无论它是从哪里调用的。当bar已优化,编译器可能会决定内联 foo ,在这一步之后它会看到(它自己的假设函数的内部表示,例如):

    function bar() {
      // Do some FOO work...
      {};
      // Do some BAR work...
    }
    

    然后它可以轻松地将未使用的对象分配放在那里。

    也就是说,正如对该问题的评论所指出的那样,这不是您需要担心的事情。 (除非您碰巧不必要地花费大量时间构建昂贵但未使用的返回值——但这似乎不太可能,因为这是相当明显的低效率,所以您很可能一开始就不会编写这样的代码。)

    特别是,与不返回任何内容相比,返回您计算出的某个值的成本,因为每个函数总是返回一些内容 - 如果它没有 return语句,那么引擎会悄悄插入一个return undefined;为你。这意味着function f1() {}function f2() { return undefined; }将编译为完全相同的代码。如果您决定写一些类似的内容:

    function overly_clever(need_result) {
      let result = do_some_work();
      if (result < 0) handle_error();
    
      if (need_result) {
        return result;
      } else {
        // Return nothing.
      }
    }
    

    然后,与用简单的 return result 替换空行之后的所有内容相比,该函数会稍稍(无法测量) ,因为“空”else -branch (自动插入 return undefined; )不比 return result 快,因此评估 need_result这种情况是浪费时间。

    所以,简而言之:不用担心。编写有意义的代码,让引擎负责优化它。

    (为了完整起见:如果您确实觉得需要进行手动优化工作,请通过测量来指导它:分析您的应用程序以查看大部分时间都花在哪里,并测量任何尝试更改的效果以查看它们是否有效是有效的。不要使用微基准,因为它们往往会产生误导。)

    关于javascript - Javascript (V8) 是否优化未使用的返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62011982/

    相关文章:

    javascript - Chrome V8 实际实现了哪个版本的 ECMAScript 标准?

    javascript - Ionic 3 JavaScript 堆内存不足

    javascript - Rails 中的 Turbolinks 与使用 javascript 的 Alpine JS 下拉列表和 Hubspot 表单冲突

    javascript - 在 jquery.carouFredSel-6.2.1.js 中找不到 Foo 元素

    javascript - jquery 数据表从 web API 接收到不正确的 json

    javascript - 如何通过 $refs 将类添加到 Vue 组件

    javascript - ReactJS:导入headroom后出现错误

    javascript - 扩展 V8 JavaScript 引擎

    eclipse - 在 Eclipse 中运行和调试 Node 项目

    eclipse - Eclipse : Logic, 中的 V8 调试器或有史以来最奇怪的错误?