Java Enums - Switch statements vs Visitor Pattern on Enums - Performance benefits?
I have been searching around for days to find an answer to this performance based issue.
After digging the Internet so far I have learned that there are couple of ways to use the Enums in java, well documented in here. Well, definitely as a starter one would like use Enums in a switch-case statement, which provides clarity and better understanding of the code. But on the other hand we have a Visitor pattern style implementation of the Enums as well, which ensures type safety and extensibility, Discussed here.Having said that, and coming back to original idea behind this question, so far I have learned that if a switch-case construct is properly designed using Enums, which ensures that case values are not sparse, and that the Enum declaration is in the same compilation unit as the switch-case statement, the java compiler performs some optimisation on the produced byte-code by implementing such construct as a Jump Table (discussed in here and elsewhere as well on Sun's website, to which I lost the link). Now, this definitely gives a boost to the performance compared to multiple/nested if-else construct.
My question is, how does java implement the visitor pattern based implementation of Enums in the resulting byte-code and what is the performance boost while compared to switch-case based implementation, if any?
And which type of implementation should I prefer, considering my Enums may grow in future and I am keen on performance as well. Currently, I have some 19 and odd constants in my Enum.
EDIT
I have a class that stores some information about variables of a game. One of the variables being an Enum type.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;
}
}
}
Later I realised of separating the information from logic, and hence created another class and moved the Enum Shape from GameObject to this new class GraphicModel, and instead of having switch-case there, I implemented constant-specific methods. And yes I did put proper import statements in either class after this modification.
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() {
//
}
};
}
}
Later on I even implemented this based on visitor pattern as suggested here
So, what I need to know is that which way of implementation is more efficient? Definitely, for switch-case to be converted to jump tables on compilation, java requires both enum declaration and switch statements in the same compilation unit. Should I use switch based implementation or constant-specific method implementation in my GraphicModel class? Rather, to be clear, what's the difference in performance?
Enums are, generally speaking, comparable in performance to int constants, if used in a switch statement (1).
Maybe you should rather consider something along the lines of constant specific method implementations? e.g.
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
And then use
getMode().color();
instead of a switch statement?!
However, I think that for a "get a color only case", there is maybe no need for methods at all.
In general, I highly recommend you Effective Java for your bookshelf. Chapter 6 would be the one that discusses Enums and Annotations.
精彩评论