2010-01-29 57 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