在Java中,将静态值全局声明与在本地变量中声明是否具有性能优势?

4
给出以下代码示例:

示例1

public class SomeClass {
    private static final int onlyUsedByMethodFoo = 1;
    // many lines of code
    public static void foo() {
        final String value = items[onlyUsedByMethodFoo];
    }
}

示例2

public class SomeClass {
    // many lines of code
    public static void foo() {
        final int onlyUsedByMethodFoo = 1;
        final String value = items[onlyUsedByMethodFoo];
    }
}

我更喜欢第二个代码示例,因为它的值在使用它的地方很接近。它只由Foo()使用。即使Foo()被频繁调用,我也看不出将其声明为全局值的优势。我唯一能看到的全局静态值的优点可能是性能方面的,但不清楚这会带来多大的性能优势。也许Java认识到了这一点并优化了字节码。

关于性能方面,是否值得全局声明常量值?性能收益是否可以证明将常量值远离程序员使用和阅读的位置的行为?


为什么在字节码中直接使用文字而不是从内存中查找值会提高性能? - Affe
这个问题可能会对你有兴趣。链接 - Rohit Jain
5个回答

5
Java编译器将所有出现的静态final字段替换为其值;局部变量是运行时堆栈帧的一部分。有关更全面的解释,请参见Java®虚拟机规范
我认为在您的情况下,性能没有任何区别。

1
哇!这个问题引起了如此多的热情!感谢大家的回答。这个问题源于我与同事的一次交谈,他/她试图说服我全局静态变量比本地变量更容易维护和性能更好。在阅读回复并进行了一些本地测试后,我认为在使用变量的附近保持变量更好。看起来没有什么明显的性能损失,更容易找到,并且与代码上下文相关。谢谢大家。我很感激你们的时间。 - TERACytE

2

首先,这种微小的优化并不是您应该关注的细节。如果有什么问题,您可以在代码的更多相关部分中找到更多与性能有关的胜利。

这种微小的优化对你来说没有太大的好处,而你可能会因为微不足道的性能提升而牺牲可读性。

你的代码中没有出现显著的性能瓶颈,所以如果你进行了任何微小的优化,我不会期望有任何主要的性能提升。

至于你的主要问题,静态变量的想法有两个方面:

  • 避免使用神奇数字,从而使你的意图更加清晰。
  • 如果您的值需要更改,您只需要更改一个地方而不是多个地方。

我认为,如果其他类没有使用它,那么它就不需要是public。我仍然建议它是类变量,所以它将具有样例1的样式,但带有声明private static final int onlyUsedByMethodFoo = 1;


0

特定 Java 实现/版本的 JIT 编译器可能会根据其可以推断出的代码各种信息进行特殊优化。然而,一般来说,它能够比一个 final 方法变量更容易地优化一个 static final 类成员。

所涉及的变量是原始类型(int)这一事实可能会改变情况;如果它是一个引用类型,那么它将很难被优化。由于它不是对象,因此您无法对引用相等性或类似的任何东西使用技巧;请考虑以下示例并与您的 final int 进行比较:

void foo() {
final Object o = new SomeObject();
}

我认为,在这种情况下,final 对性能毫无帮助,因为语义的期望是,如果你在单独的方法调用之间比较 o,它应该是一个不同的对象,即它不会与前一个方法调用中的 o 相等。但是,如果你将其定义为静态的最终类成员,那么你就真正拥有了一个单例对象。

对于方法中的 final 原始类型 是否必须进行JIT优化并不清楚,因为它可能被优化为仅在一个位置存储,但是对于引用类型来说,类成员在内存/CPU方面的开销会(稍微)更低。


0
对于这种情况,性能(至少对于原始类型)并不是问题。更重要的是“代码质量”,即您的代码的一致性、可读性和清晰度。 因此,如果您想要一个特定上下文的变量,请在它真正属于的地方定义它,并且不要搞乱全局上下文。

0

进行过早的优化并不是一个好习惯。集中精力于设计,好的设计易于扩展和维护。如果您有一个好的设计和代码,识别性能问题(如果有)将不会很麻烦,并且可以解决。再次强调——永远不要进行过早的优化。此外,现在的编译器已经调整过,可以生成优化的字节码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接