andyInCambridge
andyInCambridge

Reputation: 1225

java compile- versus run- time computation

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?

Upvotes: 0

Views: 194

Answers (3)

The Nail
The Nail

Reputation: 8490

This is not really an answer, but a tip: Make getLocs non-static and just return the locs of the current enum:

public MapLocation[] getLocs(){
    return locs;
}

Instead of SightSensor.getLocs(someDir) you then call someDir.getLocs().

This way you avoid having to enumerate all members of the enum.

Upvotes: 0

Itay Maman
Itay Maman

Reputation: 30733

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:

Now, if I write ... inside a loop in the code, I find that there is a cost overhead the first time the code is called,

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:

public static MapLocation[] getLocs(Direction dir) {
  return valueOf(dir.name()).locs;
}

Alternatively, you can use replace the SightSensor enum with a variable of type EnumMap:

EnumMap<Direction, MapLocation[]> map = new EnumMap(Direction.class);
map.put(Direction.NORTH, new MapLocation[] {  new MapLocation(0, 1), 
                                              new MapLocation(0, 2),
                                              new MapLocation(0, 3) });
map.put(Direction.NORTH, new MapLocation[] {  new MapLocation(0, -1), 
                                              new MapLocation(0, -2),
                                              new MapLocation(0, -3) });

Then, getLocs() calls simply become map.get(dir)

Upvotes: 3

duffymo
duffymo

Reputation: 308938

Does the compiler do some weird sort of just-in-time computation?

Yes, the Java run-time does use statistics to optimize the code as it runs:

http://docs.oracle.com/javase/6/docs/technotes/tools/share/jstat.html

Nothing weird about it.

This might be pertinent as well:

Real differences between "java -server" and "java -client"?

Personally, I think you should write the code to be as easy to read as possible and not worry about optimization. The speedup probably isn't significant.

Upvotes: 2

Related Questions