用java 8编译的代码与用java 11编译的代码



我们目前有用Java 8编译的代码,但我们正在Java 11虚拟机上运行。现在,我们也在尝试将代码转移到Java 11编译时。想知道Java 8中的编译代码与Java 11中的编译代码在性能方面是否有任何好处,因为两个编译器都会产生不同的类文件(字节码(?一个与另一个在效率方面有何不同?

javac不是一个优化编译器,所以一般来说,不要期望它产生"更快";从一个版本到另一个版本的字节码。优化是JVM的一项工作。

同时,Java编译器确实支持新的语言功能,可能也支持新的JVM功能。其中一些确实对性能有影响。JDK9-JDK11中最值得注意的例子如下。

  1. JEP 280:独立字符串连接(JDK 9(。

    这个JEP改变了字符串串联表达式的编译方式。JDK9之前,字符串+表达式被翻译成

    new StringBuilder().append()...append().toString();
    

    尽管JIT可以识别这样的链,并试图在运行时对其进行优化,但这种优化是脆弱的,并不总是如预期的那样工作。使用invokedynamic编译字符串串联使JVM可以更自由地生成更好的代码。您可以在本JEP的注释中找到详细的解释和基准。

  2. JEP 181:基于嵌套的访问控制(JDK 11(

    这个JEP解决了访问嵌套类的私有成员的问题。在JDK11之前,Java编译器为它们生成了合成桥接方法(示例(。

    乍一看,这与性能无关。然而,在边缘情况下,由于内联深度限制,额外的合成方法可能会中断内联。

    基于嵌套的访问控制允许嵌套类在没有合成桥的情况下访问彼此的私有成员,从而降低意外性能降级的风险。

更新

之前我在这个列表中包括了JDK-8175883:用于增强循环的字节码生成,但正如@Holger在评论中注意到的那样;优化";实际上没有起作用。

结论

Java编译器的变化主要与新的语言/JVM功能有关。字节码级别的优化不是目标。然而,其中一些更改也可能(间接(影响性能。无论如何,重新编译代码可能带来的性能好处通常很小,以至于在实际应用程序中都不会注意到。

最新更新