2011-11-06 17 views
13

私は文字通り数十万回のタイトなループで実行される2人用ゲームを実装しています。Java Enumのパフォーマンス?

私のコードは、実際にこのようなものになります。

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

    private final int currentPlayer; 
    private final int otherPlayer; 

    ... 
} 

を私はどんなパフォーマンスヒットになるだろうかと思いまして、私は

public enum Players { 
    WhitePlayer, 
    BlackPlayer 
} 
として定義列挙型に

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

を交換することを選択します

私は、列挙型は整数定数よりも構文上の砂糖であり、テストenumのために生成されたバイトコードを調べると、それを呼び出すコードは、実際に静的メソッド呼び出しを行うのと同じだが、最初に実行されたときに設定されたいくつかの列挙型インフラストラクチャについては同じであると思われる。

私は静的定数として正しい列挙型を使用することは確かに同じか、ここで何か不足していると私の前提ですか?

+0

何百回の時間単位で何百回ですか? –

+1

良い質問です。私はゲームを24時間7日実行して(私が推測すると)何日かになるので、終了が早いほど早く結果を分析することができます。私はパフォーマンスチューニングスレッドとの典型的な戦争にこれを変えないように人々に頼みます。 –

+6

それが本当に計量だと思えば、私はそれを測定します。 –

答えて

20

マイクロベンチマークでは、整数定数の等価性を検査することは、列挙定数の等価性を検査するよりも速くなります。

しかし、実際のアプリケーションでは、ゲームはさておきませんが、これは完全に無関係です。 AWTサブシステム(または他のGUIツールキット)で起こっている事柄は、これらのマイクロパフォーマンスの問題を桁違いに矮小化します。

EDIT

私はその後、少し詳しく説明しましょう。

列挙比較は次のように進む:

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ビット整数)と32ビットリファレンス(Enum同一性)を比較するのがなぜ速いのですか? (明らかに '.equals'メソッドを使用しないでください) –

+1

答えは間違っています、downvote。 – EJP

8

パフォーマンスを気にする前に、わかりやすいコードが必要です。 プロファイリング結果(推測なし!)までは、列挙型はボトルネックであり、パフォーマンスについては忘れて、理解しやすいものを使用してください。それはしばらくの間、実行されています後

+4

いいね!質問に答えない! –

+2

これはあなたの質問に答えるだけで、あなたはその答えを理解していないか、あまり好きではありません。まあ、それはあなたの選択です。 – unbeli

+0

それは正解です。 intを使用することとenumを使用することの違いを知ることはできません。 – MeBigFatGuy

2

JITは

もちろんのこと、列挙型は、より読みやすく、より確実なているあなたのコード内のエラーを確認する必要があり、この関係のないようなものを作る多くのことを最適化する

+0

何かのようなものを最適化しますか? – EJP

0

あなた仮定は正しい。 Javaではenumのインスタンスが1つしかないので、==はintを比較するほど効率的です。

+0

答えは間違っています、downvote。 –

+0

@IngoKegel何が正確に間違っていますか? – EJP

+0

私の答えを編集してください –