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

新手上路,请多包涵

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

例如:

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

在上述情况下, str 可以是 final 但这通常被忽略。

当一个方法永远不会被覆盖时,我们可以使用 final 关键字。同样,对于不会被继承的类。

在任何或所有这些情况下使用 final 关键字真的可以提高性能吗?如果是这样,那又如何呢?请解释。如果正确使用 final 真的对性能很重要,那么 Java 程序员应该养成什么样的习惯才能充分利用关键字?

原文由 Abhishek Jain 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 786
2 个回答

通常不会。对于虚拟方法,HotSpot 跟踪该方法是否 实际上 已被覆盖,并且能够执行优化,例如在方法未被覆盖的 假设下 进行内联 - 直到它加载一个覆盖该方法的类,此时它可以撤消(或部分撤消)这些优化。

(当然,这是假设您使用的是 HotSpot——但它是迄今为止最常见的 JVM,所以……)

在我看来,您应该基于清晰的设计和可读性而不是出于性能原因使用 final 。如果您出于性能原因想要更改任何内容,您应该在将最清晰的代码弯曲变形之前执行适当的测量 - 这样您就可以决定所获得的任何额外性能是否值得更差的可读性/设计。 (根据我的经验,这几乎不值得;YMMV。)

编辑:正如已经提到的 final 领域,值得一提的是,就清晰的设计而言,它们通常是一个好主意。它们还改变了跨线程可见性方面的保证行为:构造函数完成后,保证任何最终字段立即在其他线程中可见。根据我的经验,这可能是 final 最常见的用法,尽管作为 Josh Bloch 的“设计继承或禁止它”经验法则的支持者,我可能应该使用 final 更多经常上课…

原文由 Jon Skeet 发布,翻译遵循 CC BY-SA 2.5 许可协议

简短的回答:不用担心!

长答案:

在谈论 最终局部变量 时,请记住使用关键字 final 将帮助编译器 静态 优化代码,最终可能会产生更快的代码。例如,下面示例中的最终字符串 a + b 是静态连接的(在编译时)。

 public class FinalTest {

    public static final int N_ITERATIONS = 1000000;

    public static String testFinal() {
        final String a = "a";
        final String b = "b";
        return a + b;
    }

    public static String testNonFinal() {
        String a = "a";
        String b = "b";
        return a + b;
    }

    public static void main(String[] args) {
        long tStart, tElapsed;

        tStart = System.currentTimeMillis();
        for (int i = 0; i < N_ITERATIONS; i++)
            testFinal();
        tElapsed = System.currentTimeMillis() - tStart;
        System.out.println("Method with finals took " + tElapsed + " ms");

        tStart = System.currentTimeMillis();
        for (int i = 0; i < N_ITERATIONS; i++)
            testNonFinal();
        tElapsed = System.currentTimeMillis() - tStart;
        System.out.println("Method without finals took " + tElapsed + " ms");

    }

}

结果?

 Method with finals took 5 ms
Method without finals took 273 ms

在 Java 热点 VM 1.7.0_45-b18 上测试。

那么实际的性能提升有多少呢?我不敢说。在大多数情况下可能是微不足道的(在这个综合测试中大约 270 纳秒,因为完全避免了字符串连接 - 一种罕见的情况),但在高度优化的实用程序代码中它 可能 是一个因素。在任何情况下,原始问题的答案都是 _肯定的,它可能会提高性能,但充其量只是略微提高_。

除了编译时的好处,我找不到任何证据表明使用关键字 final 对性能有任何可衡量的影响。

原文由 rustyx 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题