Java static 修饰符对运行时性能有积极影响吗?

Does the Java static modifier have a positive effect on runtime performance?

public class A {
    private int a;
    private static int b;

    public A(int num) {
        this.a = num;
        this.b = num;

        // which one is quickest?
        this.computeA();
        this.computeB();
    }

    public int computeA() {
        return this.a * this.a;
    }

    public static int computeB() {
        return b * b;
    }
}

在上面的代码中,变量 b 和方法 computeB() 上的 static 修饰符对 JVM 上的运行时有任何积极的性能影响吗?

如果比较 invokestatic jvm instruction does compared to invokevirtual or invokeinterface,您会发现 invokestatic 应该更快。与 invokevirtual 相比,method 只在静态方法列表中查找(更小),忽略 class 层级。 invokeinterface 做了更多的工作,因为它无法优化方法查找(因此是所有方法中最慢的)。

像大多数这些问题一样,您应该首先考虑清晰度,其次才是性能。使代码清晰和简单,它可能会表现得相当好。

就清晰度而言,主要优点是明确表示您没有在方法中使用 this。这样可以更轻松地重构方法。

正如@OceanLife 提到的,应避免使用可变静态字段。静态字段就像单例,它们更难进行单元测试和线程安全。

虽然我会尽可能使用方法 static,但我会避免使用 static 字段,除非它们是不可变的。

在方法上使用 static 有两个理论上的性能优势

  • 表示栈上少传递了一个对象
  • 它不能被覆盖,所以它不是 "virtual"

实际上,JIT 可以优化大部分差异,但由于您的代码 运行 足以进行优化,因此可以产生很小的差异。

顺便说一句 运行将您的代码充分优化以进行优化将会产生很大的不同。

我没有尝试对这种情况进行任何基准测试,但使用 static 键盘(特别是在使用 Java ME/Android 进行开发时)对性能有积极影响。由于内联以及 所谓的 'warm-up' 期间之后的后续 re-JIT'ing,一些估计讨论了 20% 的执行速度提升。

也就是说,有状态静态方法不好。最近,重量级 Google/Square 开发人员一直在与 wider community.

讨论这个问题