Java枚举的性能?

2022-09-02 00:29:00

我正在实现一个2人游戏,它将在一个紧密的循环中运行数十万次,然后性能至关重要。

我的代码实际上看起来像这样:

public class Table {
    private final int WHITE_PLAYER = +1;
    private final int BLACK_PLAYER = -1;

    private final int currentPlayer;
    private final int otherPlayer;

    ...
}

我想知道我是否会受到任何性能影响,我会选择替换吗?

private final int WHITE_PLAYER = +1;
private final int BLACK_PLAYER = -1;

到定义为

public enum Players {
    WhitePlayer,
    BlackPlayer
}

我的想法是枚举只是整数常量的语法糖,并且仔细查看为测试枚举生成的字节码以及调用它的代码,似乎表明使用它们确实与进行静态方法调用相同,但对于首次运行时设置的某些枚举基础结构。

我的假设是,使用枚举作为静态常量确实是一样的,还是我在这里遗漏了一些东西?


答案 1

在微基准测试中,是的,检查整数常数相等性将比检查枚举常数相等性更快。

但是,在实际的应用程序中,更不用说游戏了,这将是完全无关紧要的。AWT子系统(或任何其他GUI工具包)中发生的事情使这些微观性能考虑因素相形见绌。

编辑

那么,让我稍微详细阐述一下。

枚举比较如下所示:

aload_0
getstatic
if_acmpne

小整数的整数比较如下所示:

iload_0
iconst_1
if_icmpne

显然,第一个比第二个工作量更大,尽管差异很小。

运行以下测试用例:

class Test {

    static final int ONE = 1;
    static final int TWO = 2;

    enum TestEnum {ONE, TWO}

    public static void main(String[] args) {
        testEnum();
        testInteger();
        time("enum", new Runnable() {
            public void run() {
                testEnum();

            }
        });
        time("integer", new Runnable() {
            public void run() {
                testInteger();
            }
        });
    }

    private static void testEnum() {
        TestEnum value = TestEnum.ONE;
        for (int i = 0; i < 1000000000; i++) {
            if (value == TestEnum.TWO) {
                System.err.println("impossible");
            }
        }
    }

    private static void testInteger() {
        int value = ONE;
        for (int i = 0; i < 1000000000; i++) {
            if (value == TWO) {
                System.err.println("impossible");
            }
        }
    }

    private static void time(String name, Runnable runnable) {
        long startTime = System.currentTimeMillis();
        runnable.run();
        System.err.println(name + ": " + (System.currentTimeMillis() - startTime) + " ms");
    }
}

你会发现枚举比较比整数比较慢,在我的机器上大约1.5%。

我想说的是,这种差异在实际应用程序中并不重要(“过早优化是所有邪恶的根源”)。我在专业的基础上处理性能问题(请参阅我的个人资料),我从未见过可追溯到此类的热点。


答案 2

在关心性能之前,您应该关心拥有漂亮且可读的代码。在分析结果(不加猜测!)显示枚举是瓶颈之前,请忘记性能并使用任何更易于理解的内容。


推荐