2011-11-06 55 views
13

我正在實施一個雙人遊戲,它將在幾十萬次的緊密循環中運行,然後是性能最重要的。Java枚舉的性能?

我的代碼實際上看起來是這樣的:

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 
} 
枚舉

我的想法是,枚舉只是整數常量上的語法糖,查看爲測試枚舉生成的字節碼以及調用它的代碼似乎表明,使用它們確實與創建靜態方法調用相同,但是對於某些在第一次運行時設置的枚舉基礎結構。

是我的假設,它確實是相同的使用枚舉作爲靜態常量正確或我在這裏丟失的東西嗎?

+0

每個單位幾十萬次? –

+1

好問題。我會在幾天內全天候運行遊戲(我估計),所以他們結束得越快,我就越早分析他們的結果。我請求人們不要把它變成反對性能調整線程的典型戰爭.. –

+6

如果它認爲它真的被測量,我會測量它。 –

回答

20

在一個微基準測試中,是的,檢查整數常量相等性將比檢查枚舉常量相等更快。

然而,在一個真實的應用程序中,更不用說一個遊戲,這將是完全不相關的。 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

「然而,在真實的應用程序中,更不用說遊戲了,這將是完全不相關的。AWT子系統(或任何其他GUI工具包)中發生的事情使這些微觀性能考慮因素的數量減少了許多。所以你假設這個遊戲的確有一個GUI?完全錯誤! –

+1

爲什麼比較32位引用(枚舉標識符相等)和32位整數更快? (顯然你不會使用'.equals'方法) –

+1

答案是不正確的,downvote。 – EJP

8

在關心性能之前,您應該關心編寫漂亮可讀的代碼。直到你的分析結果(沒有猜測!)顯示枚舉是瓶頸,忘記性能和使用更容易理解的內容。它已經運行了一段時間後

+4

不錯!不回答這個問題! –

+2

這回答你的問題,你只是不明白或不喜歡答案。那麼,那是你的選擇。 – unbeli

+0

這絕對是正確的答案。您將無法分辨使用整數和使用枚舉的區別。 – MeBigFatGuy

2

JIT將優化很多事情做這樣的事情無關

何況枚舉是更具可讀性和更簡單的,你應該做的錯誤在你的代碼

+0

會優化什麼東西? – EJP

0

你假設是正確的。 Java可以確保只有一個枚舉實例,所以==與比較int一樣有效。

+0

答案是不正確的,downvote。 –

+0

@IngoKegel究竟是什麼特別錯誤? – EJP

+0

請參閱編輯我的答案 –