Java优化:(Hotspot/Dalvik)优化返回常量的最终方法?

Java优化:(Hotspot/Dalvik)优化返回常量的最终方法?,java,android,jit,dalvik,jvm-hotspot,Java,Android,Jit,Dalvik,Jvm Hotspot,有人能告诉我Hotspot或Dalvik是否足够聪明,可以内联调用返回常量(静态final)int值的final方法吗?理想情况下,方法调用将替换为常量。这可能是在类加载时进行的,也可能是通过JIT进行的 这对我正在处理的一些代码的设计有影响。我认为答案是“不,优化不会发生,因为没有或存在final关键字”,至少在HotSpot VM上是这样。但由于其他因素,优化可能会发生 下面是Brian Goetz在(很抱歉引用这么长的话)中所说的: 就像许多关于Java性能的神话一样,错误的信念 将类或方

有人能告诉我Hotspot或Dalvik是否足够聪明,可以内联调用返回常量(静态final)int值的final方法吗?理想情况下,方法调用将替换为常量。这可能是在类加载时进行的,也可能是通过JIT进行的


这对我正在处理的一些代码的设计有影响。

我认为答案是“不,优化不会发生,因为没有或存在
final
关键字”,至少在HotSpot VM上是这样。但由于其他因素,优化可能会发生

下面是Brian Goetz在(很抱歉引用这么长的话)中所说的:

就像许多关于Java性能的神话一样,错误的信念 将类或方法声明为最终结果可以获得更好的性能 广泛持有但很少审查。争论的焦点是 方法或类作为编译器可以内联方法的最终手段 更积极地调用,因为它知道在运行时这是 肯定是要调用的方法的版本。但是 这根本不是事实。就因为类X是根据 最终的Y类并不意味着相同版本的Y类将被删除 在运行时加载。因此编译器不能内联这样的跨类 方法安全地调用,无论是否为final。只有当一个方法是私有的时 编译器可以自由内联它,在这种情况下,最终的关键字 多余的

另一方面,运行时环境和JIT编译器有更多的功能 关于实际加载了哪些类的信息,这些信息会产生很大的影响 比编译器更好的优化决策。如果运行时 环境知道没有加载扩展Y的类,所以它 可以安全地内联调用Y的方法,而不管Y是否为 final(只要在 稍后加载Y的子类)。所以现实是,虽然最终 这可能是对一个愚蠢的运行时优化器的有用提示 执行任何全局依赖性分析,其使用实际上并不 启用很多编译时优化,而不是 执行运行时优化的智能JIT

还有一个很好的解释。

如果JIT编译器检测到热点,那么它可能会执行内联操作,这是字节码中经常调用的一种方法,可能值得花费一些CPU时间将字节码编译成机器码

JIT编译器很有可能内联一个
final
方法(因为它不能被覆盖)。如果该方法只返回一个常量值,那么情况会更好

但我的理解是,如果调用方法不是热点,那么它就不会被编译,也不会有
final
方法的内联


()

或者,预计会针对这种情况优化Java字节码。

您能解释一下为什么这种透明的微优化会对您的设计产生影响吗?
Java-XX:+printpotassembly
可以帮助您发现我试图与特定类型的每个子类共享一个(contant)值,因此,重载受保护的访问器方法来执行此操作,而不是将其提供给构造函数以存储在父类定义的字段中。额外的开销对使用是非常重要的。引用中没有说JIT没有内联final方法。它说它可以内联方法,即使它们不是final,并且不需要使用final关键字来获得优化。正如我所理解的,优化很可能会发生。但是final或多或少是无用的。是的,我也理解优化可能会发生——但不是因为
final
字段的缺失或存在。澄清了答案。