简体   繁体   中英

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?

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)

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM