有人能告诉我,Hotspot或Dalvik是否足够聪明,可以内联调用返回常量(静态最终)int值的final方法?理想情况下,方法调用将被常量替换。这可能是在类加载时或通过JIT。
这对我正在研究的一些代码的设计有影响。
答案 0 :(得分:12)
我认为答案是“不,优化不会因为final
关键字的存在或存在而发生”,至少在HotSpot VM上是这样。但由于其他因素,优化可能会发生。
以下是Brian Goetz在this article中所说的内容(对于长篇引言感到抱歉):
像许多关于Java性能的神话,错误的信念 将类或方法声明为最终结果以获得更好的性能 广泛持有但很少被审查。这个论点是宣称a 方法或类作为final意味着编译器可以内联方法 更积极地打电话,因为它知道在运行时这是 肯定是将要调用的方法的版本。但 这是不正确的。只是因为编译了X类 最终的Y类并不意味着Y级的相同版本 在运行时加载。所以编译器不能内联这样的跨类 方法安全地调用,最终或不调用。只有方法是私有的才能 编译器可以自由地内联它,在这种情况下,最后的关键字会 多余的。
另一方面,运行时环境和JIT编译器有更多 有关哪些类实际加载的信息,并且可以做很多 比编译器更好的优化决策。如果是运行时 环境知道没有加载任何扩展Y的类,然后它 无论Y是否,都可以安全地内联调用Y的方法 final(只要它可以使这样的JIT编译的代码无效,如果一个 稍后加载Y的子类)。所以现实是最终的 对于没有的哑运行时优化器可能是一个有用的提示 执行任何全局依赖性分析,实际上并没有使用它 启用非常多的编译时优化,而a不需要 智能JIT执行运行时优化。
还有一个很好的帖子,为什么final is not final any more, at least in Java 5。
答案 1 :(得分:0)
内联是JIT编译器可能在检测到热点时所执行的操作,这是一个被调用的字节代码中的方法通常,将字节代码编译成机器代码可能需要花费一些CPU时间。
JIT编译器很可能会内联final
方法(因为它不能被覆盖)。如果该方法只返回一个常量值,那么机会会更好。
但这是我的理解 - 如果调用方法不是热点,那么它将不会被编译,并且不会内联final
方法。
答案 2 :(得分:0)
或者,Soot可以针对这种情况优化Java字节码。