java finals 是否有助于编译器创建更高效​​的字节码? [英] Do java finals help the compiler create more efficient bytecode?

查看:27
本文介绍了java finals 是否有助于编译器创建更高效​​的字节码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能的重复:
在Java中使用final关键字会提高性能吗?

final 修饰符具有 不同的后果java取决于您将其应用于什么.我想知道的是,它是否另外可以帮助编译器创建更高效​​的字节码.我想这个问题深入到 JVM 的工作方式,并且可能是特定于 JVM 的.

The final modifier has different consequences in java depending on what you apply it to. What I'm wondering is if additionally it might help the compiler create more efficient bytecode. I suppose the question goes deep into how the JVM work and might be JVM specific.

那么,根据您的专业知识,以下任何一项对编译器有帮助,还是您只是出于正常的 Java 原因使用它们?

So, in your expertise, do any of the following help the compiler, or do you only use them for the normal java reasons?

  • 期末班
  • 最终方法
  • 最后的字段
  • 最终方法参数

谢谢!

感谢您的所有回答!请注意,正如@Zohaib 建议的那样,我的问题是

Thanks for all your answers! Please note that, as @Zohaib suggested, my question is a duplicate of this. I didn't search well enough before posting. I'm not deleting it because you guys made good contributions, but the answers could be merged. I'll let the "vote for close" system decide unless told otherwise.

推荐答案

如果您使用 final,字节码的效率不会显着提高或降低,因为 Java 字节码编译器通常在优化方式方面做得很少.效率奖励(如果有)将在 JIT 编译器生成的本机代码中1.

The bytecodes are not significantly more or less efficient if you use final because Java bytecode compilers typically do little in the way optimization. The efficiency bonus (if any) will be in the native code produced by the JIT compiler1.

理论上,使用 final 为 JIT 编译器提供了一个提示,可以帮助它进行优化.在实践中,最近的 HotSpot JIT 编译器可以通过忽略您的提示来做得更好.例如,现代 JIT 编译器通常执行全局分析,以确定给定的方法调用是否是对应用程序当前加载的类上下文中的叶方法的调用.此分析比您的 final 提示更准确,运行时甚至可以检测何时加载了使分析无效的新类……并为受影响的代码重做分析和本机代码生成.

In theory, using the final provides a hint to the JIT compiler that should help it optimize. In practice, recent HotSpot JIT compilers can do a better job by ignoring your hints. For instance, a modern JIT compiler typically performs a global analysis to find out if a given method call is a call to a leaf method in the context of the application's currently loaded classes. This analysis is more accurate than your final hints can be, and the runtime can even detect when a new class is loaded that invalidates the analysis ... and redo the analysis and native code generation for the affected code.

使用final还有其他语义后果:

There are other semantic consequences for use of final:

  • Declaring a variable as final stops you from accidentally changing it. (And expresses your intention to the reader.)
  • Declaring a method as final prevents overriding in a subclass.
  • Declaring a class as final prevents subclassing entirely.
  • Declaring a field as final stops a subclass from changing it.
  • Declaring a field as final has important consequences for thread-safety; see JLS 17.5.

在适当的情况下,这些都是好的.但是,很明显,它们通过创建子类限制了您重用的选择.在决定是否使用final时需要考虑这一点.

In the right circumstances, these can all be good. However, it is clear that they limit your options for reuse by creating subclasses. This needs to be considered when deciding whether or not to use final.

好的做法是使用 final 来(广义上)表达您的设计意图,并实现您需要的其他语义效果.如果您仅将 final 用作优化提示,您将不会取得太大成果.

So good practice is to use final to (broadly speaking) express your design intentions, and to achieve other semantic effects that you require. If you use final solely as an optimization hint, you won't achieve much.

在一些例外情况下,final 可能会导致某些平台上的小幅性能改进.

There are a couple of exceptions where final could lead to small performance improvements on some platforms.

  • 在某些情况下,将字段声明为 final 会改变字节码编译器处理它的方式.我在上面举了一个例子.另一种是常量变量"情况(JLS 4.12.4),其中static final 字段的值在当前类和其他类中由字节码编译器内联,并且这可能会影响观察到的代码行为.(例如,引用一个常量变量不会触发类初始化.因此,添加一个final 可能改变类初始化的顺序.)

  • Under certain circumstances, declaring a field as final changes the way that the bytecode compiler deals with it. I've given one example above. Another is the "constant variable" case (JLS 4.12.4) where a static final field's value will be inlined by the bytecode compiler both in the current classes, and in other classes, and this may affect the observed behavior of code. (For example, referring to a constant variable will NOT trigger class initialization. Hence, the addition of a final may change the order of class initialization.)

可以想象,将字段或本地参数声明为 final 可能会允许进行其他情况下无法完成的次要 JIT 编译器优化.但是,任何可以声明为 final 的字段也可以被 JIT 编译器推断为有效的 final.(只是不清楚 JIT 编译器是否真的这样做了,以及这是否会影响生成的本机代码.)

It is conceivable that declaring a field or local parameter as final may allow minor JIT compiler optimization that wouldn't otherwise be done. However, any field that can be declared as final could also be inferred to be effectively final by the JIT compiler. (It is just not clear that the JIT compiler actually does this, and whether that affects the generated native code.)

然而,底线保持不变.您应该使用 final 来表达您的设计意图,而不是作为优化提示.

However the bottom line remains the same. You should use final to express your design intentions, not as an optimization hint.

1 - 这个答案假设我们谈论的是最近的 JVM,它有一个很好的 JIT 或 AOT 编译器.1) 最早的 Sun Java 实现根本没有 JIT 编译器.2) 早期的 Android Java 实现的编译器在优化方面做得很差.事实上,早期的 Android 开发人员文档建议进行各种源代码级的微优化以进行补偿.此建议已被删除.

这篇关于java finals 是否有助于编译器创建更高效​​的字节码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆