java决赛有助于编译器创建更高效​​的字节码吗?

Miq*_*uel 41 java optimization micro-optimization

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

最后的修改有不同的后果取决于你把它应用到什么在java中.我想知道的是,如果另外它可能有助于编译器创建更高效​​的字节码.我想这个问题深入探讨了JVM的工作原理以及JVM的具体情况.

那么,根据您的专业知识,请执行以下任何一项帮助编译器,或者您是否仅出于正常的java原因使用它们?

  • 最后的课程
  • 最后的方法
  • 最后的领域
  • 最终方法论点

谢谢!

编辑:谢谢你的所有答案!请注意,正如@Zohaib建议的那样,我的问题与重复.在发布之前我搜索得不够好.我不是删除它,因为你们做出了很好的贡献,但答案可以合并.除非另有说明,否则我会让"投票结束"系统决定.

Ste*_*n C 59

如果使用final字节码,则字节码的效率并不高或低,因为Java字节码编译器通常在优化方式上做的很少.效率奖励(如果有的话)将在JIT编译器生成的本机代码中.

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

因此,最佳实践是final(广泛地说)用来表达您的设计意图,并实现您需要的其他语义效果.(例如,使用final修饰符可以在实现线程安全的不可变类型中发挥重要作用;请参阅JLS 17.5)如果您使用final优化提示,则不会实现太多,并且您将使代码更难以修改和扩展.

UPDATE

这有几个例外(如下所述):

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

  • 可以想象,声明字段或本地参数final可能允许小的JIT编译器优化,否则将无法完成.然而,可以声明为final的任何领域可能也被推断为通过JIT编译器有效决赛.(目前尚不清楚JIT编译器是否实际执行此操作,以及是否会影响生成的本机代码.)

但是,我以前的建议适用.使用final来表达你的设计意图,而不是作为一个优化提示.

  • +1:除了编译器的持续评估.;) (3认同)

Tho*_*mas 11

这个问题已经被提出了很多问题,答案通常是:编译器可能会进行一些优化(例如内联常量,这是最终的静态字段)但通常你不应该为此烦恼,因为这些性能提升实际上可能并不明显.只需将final关键字用于"正常"Java原因(使字段或参数不可变,防止子类化或覆盖方法).


Pet*_*rey 6

我建议你用你的代码进行测试.在某些情况下,它可以使编译器与众不同,但它更有可能对JIT产生影响.当谈到微基准和微调时应该有什么不同,实际上有什么区别往往是不一样的,只有好的测试才是确定的方法.

你遇到的另一个问题是JVM一直在不断改进,而且在之前可能不再适用的技巧也会产生很大的影响.例如,在Java 5.0 Lock中比synchronized在Java 6中快得多,差异要小得多,而且synchronized可以更快.

通常,使代码简单,清晰且易于维护是一个好主意,这也将导致高效的代码.