2010-01-29 58 views
7

我一直在尋找幾天來找到這個基於性能問題的答案。
到目前爲止,在挖掘互聯網之後,我瞭解到有幾種方法可以使用java中的Enums,這些方法在here中有詳細記錄。 那麼,絕對作爲一個初學者,你可以在switch case聲明中使用Enums,它提供了清晰和更好的代碼理解。但另一方面,我們也有一個訪問者模式樣式實現的枚舉,以及確保類型的安全性和可擴展性,討論hereJava枚舉 - 切換語句與訪問者模式對枚舉 - 性能好處?

話雖如此,並回到這個問題背後的原始思路,到目前爲止,我已經瞭解到,如果一個switch-case構造是使用Enums正確設計的,它確保了case值不稀疏,並且Enum聲明與switch-case語句位於同一個編譯單元中,java編譯器通過實現如跳轉表(在here以及其他地方以及在Sun的網站中討論的那樣,將I失去了鏈接)。現在,與多重/嵌套if-else構造相比,這肯定會提升性能。

我的問題是,java如何在生成的字節碼中實現Enums的訪問者模式實現,並且與基於的開關實例(如果有)相比,性能提升是多少?

我應該選擇哪種類型的實現,考慮到我的枚舉可能會在將來增長,我也熱衷於性能。目前,我的Enum中有19個和奇數常量。


編輯
我有一個存儲有關遊戲的一些變量信息的類。其中一個變量是Enum類型。

public class GameObject { 
    private Shape mShape; 

    public Shape getShape() { 
     return mShape; 
    } 
    . 
    . 
    . 

    public static enum Shape { 
     SHAPE1, SHAPE2, SHAPE3, SHAPE4, ..., SHAPE20 
    }; 

    public void drawShape() { 
     switch (this.mShape) { 
     case SHAPE1: 
      drawShape1(); 
      break; 
     case SHAPE2: 
      drawShape2(); 
      break; 
     case SHAPE3: 
      drawShape3(); 
      break; 
     case SHAPE4: 
      drawShape4(); 
      break; 
     . 
     . 
     . 
     . 
     . 
     case SHAPE20: 
      drawShape20(); 
      break; 
     default: 
      drawUnknown(); 
      break; 
     } 
    } 

}

後來才知​​道分離邏輯的信息的,因此創建了另一個類和移動枚舉形狀遊戲物體到這個新的類GraphicModel,而不是有切換案例那裏,我實現了個常量特定方法。是的,我確實在這個修改之後在任何一個類中都輸入了正確的導入語句

public class GraphicModel { 
    public void drawGraphicFromObject(GameObject gameObject) { 
     gameObject.getShape().draw(); 
    } 

    public static enum Shape { 
     // This method is not public, instead is only called by GraphicModel 
     abstract void draw(); 

     SHAPE1 { 
      @Override 
      void draw() { 
       // some transformations 
      } 
     }, 
     SHAPE2 { 
      @Override 
      void draw() { 
       // Some different transformation 
      } 
     }, 
     SHAPE3 { 
      @Override 
      void draw() { 
       // Yet another transform 
      } 
     }, 
     . 
     . 
     . 
     . 
     UNKNOWN { 
      @Override 
      void draw() { 
       // 
      } 
     }; 
    } 
} 

後來我甚至實現此基礎上訪問者模式的建議here

所以,我需要知道的是,它的實現方式更有效?當然,對於的switch-case轉換爲跳轉表上編譯,Java要求既枚舉聲明和開關語句在同一編譯單元。 我應該使用開關爲基礎的實現還是恆定特定的方法實現在我的GraphicModel類? 相反,要清楚,性能有什麼不同?

+0

請修復鏈接 – 2010-01-29 18:18:47

+2

您是否有一個最清晰編寫的代碼示例,以及規範和測試結果,顯示它如何不符合規範?如果不是,你不應該考慮這些線。如果是這樣,發佈清晰的代碼,我打賭我們可以找到一些更重要的優化。 – 2010-01-29 18:27:43

+0

鏈接的SO問題告訴我們Enums如何與Visitor模式一起使用,而不是「訪問者模式Enums的實現」,我認爲如果你告訴你想要解決什麼問題會更好,一旦你看到枚舉可以用作問題的解決方案,然後你可以看看它是否需要優化 – sateesh 2010-01-29 18:28:38

回答

4

枚舉是,一般說來,在可比的性能INT常數,如果在一個開關聲明(1)使用。

也許你應該寧願考慮一些沿着不變的具體方法實現的東西?例如

public enum Mode { 

    ON { Color color() {return Color.GREEN;}}, 
    OFF { Color color() {return Color.RED;}}, 
    STANDBY { Color color() {return Color.YELLOW;}}, 
    DEFAULT { Color color() {return Color.BLACK;}}; 

    abstract Color color(); 

}//enum Mode 

然後用

getMode().color(); 

代替開關聲明?

但是,我認爲對於「僅獲取顏色的情況」,可能根本就不需要方法。

一般來說,我強烈建議你Effective Java爲您的書架。第6章將討論Enums和Annotations

+0

感謝您的建議,但這正是我第二次做的。我也會看看這本書。 – Darkfish 2010-01-30 07:12:54