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

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

在Java中,我们看到许多final可以使用关键字的地方,但它的使用并不常见。

例如:

String str = "abc";System.out.println(str);

在上述情况下,str可以final但通常不会这样做。

当一个方法永远不会被覆盖时,我们可以使用final关键字。类似地,如果一个类不会被继承。

在任何或所有这些案例中使用final关键字是否真的能提高性能?如果是这样,那怎么样?请解释。如果正确使用final对性能至关重要,那么Java程序员应该养成哪些习惯来充分利用关键字?


catspeake
浏览 477回答 3
3回答

繁星淼淼

通常不是。对于虚方法,HotSpot会跟踪方法是否实际被覆盖,并且能够在假设方法尚未被覆盖的情况下执行优化,例如内联- 直到它加载一个覆盖方法的类,此时它可以撤消(或部分撤消)这些优化。(当然,这假设您正在使用HotSpot - 但它是迄今为止最常见的JVM,所以...)在我看来,你应该final基于清晰的设计和可读性而不是出于性能原因。如果您出于性能原因想要更改任何内容,则应在将最清晰的代码变形之前执行适当的测量 - 这样您就可以决定是否所获得的额外性能值得更差的可读性/设计。(根据我的经验,它几乎不值得; YMMV。)编辑:由于已经提到了最后的领域,所以值得提出的是,无论如何,在清晰的设计方面,它们通常都是个好主意。它们还在跨线程可见性方面改变了保证行为:在构造函数完成之后,任何最终字段都保证在其他线程中立即可见。这可能是final我经验中最常见的用法,虽然作为Josh Bloch的“继承设计或禁止它的设计”的支持者,我应该final更频繁地使用课程......

手掌心

在谈论最终的局部变量时请记住,使用关键字final将有助于编译器静态优化代码,这最终可能导致更快的代码。例如,a + b下面示例中的最终字符串是静态连接的(在编译时)。public&nbsp;class&nbsp;FinalTest&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;final&nbsp;int&nbsp;N_ITERATIONS&nbsp;=&nbsp;1000000; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;String&nbsp;testFinal()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;final&nbsp;String&nbsp;a&nbsp;=&nbsp;"a"; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;final&nbsp;String&nbsp;b&nbsp;=&nbsp;"b"; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;a&nbsp;+&nbsp;b; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;String&nbsp;testNonFinal()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;a&nbsp;=&nbsp;"a"; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;b&nbsp;=&nbsp;"b"; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;a&nbsp;+&nbsp;b; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long&nbsp;tStart,&nbsp;tElapsed; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tStart&nbsp;=&nbsp;System.currentTimeMillis(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;N_ITERATIONS;&nbsp;i++) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;testFinal(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tElapsed&nbsp;=&nbsp;System.currentTimeMillis()&nbsp;-&nbsp;tStart; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Method&nbsp;with&nbsp;finals&nbsp;took&nbsp;"&nbsp;+&nbsp;tElapsed&nbsp;+&nbsp;"&nbsp;ms"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tStart&nbsp;=&nbsp;System.currentTimeMillis(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;N_ITERATIONS;&nbsp;i++) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;testNonFinal(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tElapsed&nbsp;=&nbsp;System.currentTimeMillis()&nbsp;-&nbsp;tStart; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Method&nbsp;without&nbsp;finals&nbsp;took&nbsp;"&nbsp;+&nbsp;tElapsed&nbsp;+&nbsp;"&nbsp;ms"); &nbsp;&nbsp;&nbsp;&nbsp;}}结果?Method&nbsp;with&nbsp;finals&nbsp;took&nbsp;5&nbsp;msMethod&nbsp;without&nbsp;finals&nbsp;took&nbsp;273&nbsp;ms在Java Hotspot VM 1.7.0_45-b18上测试。那么实际的性能提升了多少?我不敢说。在大多数情况下可能是边缘的(在这个综合测试中大约270纳秒,因为完全避免了字符串连接 - 这是一种罕见的情况),但在高度优化的实用程序代码中,它可能是一个因素。在任何情况下,原始问题的答案都是肯定的,它可能会提高性能,但最多只是略微提高。除了编译时的好处,我找不到任何证据表明关键字的使用final对性能有任何可衡量的影响。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java