I’m trying to understand compile versus run-time computation in java. I have the following
enum
public enum SightSensor{
NORTH (new MapLocation[]{new MapLocation(0,1),
new MapLocation(0,2),
new MapLocation(0,3)}),
SOUTH (new MapLocation[]{new MapLocation(0,-1),
new MapLocation(0,-2),
new MapLocation(0,-3)});
private final MapLocation[] locs;
SightSensor(MapLocation[] locs){
this.locs = locs;
}
public static MapLocation[] getLocs(Direction dir){
if (dir == Direction.NORTH)
return NORTH.locs;
if (dir == Direction.SOUTH)
return SOUTH.locs;
}
};
In words, I want to define a constant mapping between a Direction and an array of
MapLocations. (Perhaps this is the wrong way to do this? I’m new to Java.) Now, if I
write
MapLocation[] locs = SightSensor.getLocs(Direction.SOUTH_WEST);
inside a loop in the code, I find that there is a cost overhead the first time the code
is called, implying to me it is somehow being computed/instantiated at run time. If instead
I just directly code
MapLocation[] locs = new MapLocation[]{new MapLocation(0,1),
new MapLocation(0,2),
new MapLocation(0,3)};
there is no cost overhead. I don’t understand the difference. Does the compiler do some
weird sort of just-in-time computation?
It seems that the cost you’re seeing is the class-loading cost: the first time the code accesses a class, the class-loader loads its binary (.class file) into memory. This is a one time cost that for most practical purposes is negligible.
Moreover:
How did you measure this cost? It is nearly impossible to measure the time cost of a single operation. You can measure the time needed to carry out xM passes thru a loop and then you can divide to get the amortized cost. However, measuring a single operation is difficult: you may be getting a Garbage Collection cycle, a thread-related context switch, etc. Moreover, the JIT (Just In Time) Compiler does not kick the first time a statement is executed, so measuring a single operation will usually give you a much higher cost than amortized cost over N operations.
FWIW, I would write
getLocs()as follows:Alternatively, you can use replace the SightSensor enum with a variable of type EnumMap:
Then,
getLocs()calls simply becomemap.get(dir)