Java:编译`-target`比`11`高有什么好处吗?

093gszye  于 2023-04-19  发布在  Java
关注(0)|答案(1)|浏览(134)

我从事的项目数据量很大,性能也很重要。
它目前正在使用-target 11从Kotlin编译,但在某些地方,它运行在JRE 17+上。
如果用target 17编译,性能会有什么不同吗?据我所知,11到17之间的字节码变化并不多。有没有理论文章或基准测试?
(假设我可以自己衡量,但由于项目的构建和部署方式,仅为了尝试-target 17,将所有内容迁移到Java 17将花费大量精力。升级计划稍后进行。)
下面是-source 1.4-target 1.7的一个非常古老的类似问题:Using -target higher than -source with javac

w8f9ii69

w8f9ii691#

以下是针对较新的Java版本编译(未更改)Java源代码时可能自动获得的改进列表,按其最低目标版本排序:

从这个版本开始,保存外部示例引用的合成字段在调用超级构造函数之前被初始化。这是一个稳定性/健壮性的改进,不影响性能

在此版本之前,字符串连接使用了StringBuffer,它执行了不必要的同步。从这个版本开始,字符串连接使用StringBuilder编译成代码,它不执行同步。

Foo.class这样的类文字被编译成单个字节码指令。在此版本之前,它是调用Class.forName("Foo")并在合成static字段中记住结果的语法糖。直接支持需要更少的代码,可能会稍微快一点。

这个版本引入了StackMapTables(用于普通的桌面/服务器JVM),它为验证器提供提示。这可以减少启动时间。

从这个版本开始,字符串连接被编译成单个invokedynamic指令,而不是StringBuilder上的一系列append调用。这可以显著减少字节码大小。此外,这为运行时提供了提供更快实现代码的机会。请注意,目前这仅适用于javac,而不是Eclipse的ecj

此功能允许属于嵌套的类(通常是内部类/嵌套类)直接访问其他private成员,而无需额外的帮助器方法。这将减少代码大小,并在某些情况下可能会提高性能,例如当长调用链超过内联限制时,不再使用。

在此版本之前,内部类总是有一个引用外部示例的合成字段。从这个版本开始,只有当内部类实际访问外部示例时,才会维护该字段。这可能会对垃圾收集性能产生积极影响(并稍微减少代码大小)。
因此,一般的答案是,针对较新版本重新编译源代码可能会有好处,但据我所知,从11切换到17并没有。
此外,这些改进适用于标准Java编译器,只有当其编译器也采用这些更改时才会影响Kotlin。另一方面,Kotlin编译器也可以使用Java编译器不使用的JVM/Bytecode/Platform enhancements

相关问题