Java(V8)是否优化未使用的返回值

问题描述 投票:2回答:1

假设我们有一个像这样的功能:

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

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

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

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

function foo(needTheResultValue = false) {
  // do some work...
  if (needTheResultValue) return () => {};
  // nothing is returned if the caller didn't ask for it
}
javascript v8
1个回答
2
投票

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

[一般来说,V8(据我所知,还有其他引擎)是基于每个功能进行优化的。因此,在您的示例中,如果foo被优化时,它不知道将使用还是忽略其返回值,因此无法优化它。

例外是内联:当优化调用函数时,优化编译器具有内联被调用函数的能力,例如在此示例中:

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...
}

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

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

特别是,返回任何您已经计算出的值与不返回任何东西相比,其成本为[[zero,因为每个函数总是返回某些东西-如果它​​没有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替换空行之后的所有内容的效果略微(无法测量)

slower,因为“空” else分支(自动插入了它) return undefined;不比return result快,因此评估need_result条件是浪费时间。

因此,简而言之:不用担心。编写有意义的代码,让引擎负责对其进行优化。

(为了完整性:如果您确实需要进行手动优化工作,请通过以下方法进行指导:对您的应用程序进行配置,以查看花了最多时间的地方,并评估任何尝试的更改的效果,以查看它们是否有效有效。请勿使用微基准,因为它们容易引起误解。)

© www.soinside.com 2019 - 2024. All rights reserved.