【问题标题】:How does the JVM optimize a fluent apiJVM如何优化一个fluent api
【发布时间】:2019-02-06 05:57:50
【问题描述】:

JVM可以优化这段代码吗

这段代码如何在 Java 编译器或 JVM 中得到优化,如果这段代码是用 java 编写的,我特意要求优化

Stream.of(1, 2, 3)
      .map(i -> i + 1)
      .map(i -> i + 1)
      .map(i -> i + 1);

类似

Stream.of(1, 2, 3)
      .map(i -> i + 3)

或者更加激进,用一个基本的 for 循环替换它,这可能会提高性能。

在clojure 中有一个transducer 的概念,它是一种优化,您可以将可reduce 函数组合成单个函数并消除延迟传播的开销。 JVM可以在一个fluent api中转换一些函数吗?

例如,如果我们有一个用于 Java 流的装饰器接口

decor-map(decor-map(base-map (i -> i + 1), i -> i +1), i -> i + 1)

然后我假设编译可以以某种方式尝试转换装饰器映射。但是在一个流利的 api 中这怎么可能呢?

【问题讨论】:

  • Clojure 也是一种 JVM 语言。您的意思是“Java 编译器如何优化该代码”?
  • @ernest_k Oracle/OpenJDK Java 编译器通常不会进行大量优化,而是选择在 JIT 期间在 JVM 级别完成。 JVM 会在现在或将来的版本中进行这些优化并非没有道理。
  • @yshavit 我明白这一点。我的问题是澄清 OP 是否宁愿询问编译时优化。
  • @ernest_k 好的,抱歉。我以为您是在暗示 只有 Java 编译器可以做到这一点。 :-)
  • 编辑了我的问题。我对 Java 和 JVM 如何优化这段代码很感兴趣

标签: java optimization jvm compiler-optimization


【解决方案1】:

Javac 确实没有做太多优化,据我所知,它真的只做constant folding

换句话说:许多其他语言(例如 C++)在将源代码编译为机器代码时直接应用的所有复杂优化选项...... javac 不会做任何事情。

为什么:因为这发生在运行时(有意义的地方),由 JIT 执行。

结论:您不必担心 Java 代码在“源代码方面”的性能。您尝试使用简短的方法编写简单的代码,以便 JIT 可以做到神奇并内联所有这些,并将其转换为经过优化以支持您的实际使用模式的机器代码。

【讨论】:

  • 所以对于 JIT fluent api 来说看起来就像简单的函数调用,并且可以使用相同的规则对其进行优化?
  • 我真的怀疑 JIT 今天会这样做。我的理解是它们现在基本上处于“更多功能”模式,并且会担心像这样的小优化,直到以后(在 JIT 中优化的一个优点:您的类将获得这些新的优化而无需重新编译!) .但与往常一样,如果您担心三个i + 1 电话,您的第一步应该是不要担心它们。您的第二步应该是测量您的整个应用程序,看看这些额外的调用是否真的导致您明显的减速。
  • @yshavit 是的。我试图在最后一段中表达“你在错误的地方寻找性能”,但也许我应该更明确地表达。
猜你喜欢
  • 2018-10-15
  • 1970-01-01
  • 2011-09-06
  • 1970-01-01
  • 1970-01-01
  • 2012-02-03
  • 1970-01-01
  • 2011-06-14
  • 2011-04-28
相关资源
最近更新 更多