In java, is there a general way to enforce compile-time compilation? In a programming competition I'm in we are limited by the bytecode our robot can use every round while the program is running, so if I'm able to compute things at compile time I have an advantage.
For a concrete example, lets say I want to define a variable NORTH that will be an array of MapLocations representing the squares the robot can see if facing North. If I hand code this, I can write:
public class SightSensor{
public static MapLocation[] NORTH = {new MapLocation(-2,2),
new MapLocation(-1,1),
new MapLocation(-1,2),
new MapLocation(0,1),
new MapLocation(0,2),
new MapLocation(0,3),
new MapLocation(1,1),
new MapLocation(1,2),
new MapLocation(2,2)};
}
which represents that the robot can see all squares in a 90 degree arc about due north within a distance squared of 9. Now, my robots can see in all cardinal directions, and some can see farther than others. It would be rather tedious and seemingly bad form to hand code each possible sight (distance, direction) pair. Hence, I wrote a function
public static MapLocation[] getSensorLocs(int r, Direction dir){ ... bla ... }
that automatically computes the locations, so I can re-write the SightSensor class as
public class SightSensor{
public static MapLocation[] NORTH = getSensorLocs(3, Direction.NORTH);
}
The only problem is now when by robot tries to use the NORTH variable, it has to spend the time to run the getSensorLocs method, so it is more expensive than the hand-written version. Can I force that computation to be run at compile-time, i.e. be "symbolically replaced" in an appropriate sense?
Now that I understand you are optimising for bytecode size, you can use the following approach.
// 8 bytes per field.
public static MapLocation[] NORTH = locations("\u006a\u0079\u007a\u0089\u008a\u008b\u0099\u009a\u009b\u00aa");
// 57 bytes.
public static MapLocation[] locations(String s) {
final int len = s.length();
MapLocation[] locations = new MapLocation[len];
for (int i = 0; i < len; i++) {
char ch = s.charAt(i);
locations[i] = new MapLocation((ch >> 4) - 8, (ch & 0xf) - 8);
}
return locations;
}
static class MapLocation {
public MapLocation(int x, int y) {
System.out.println("x=" + x + ", y=" + y);
}
}
prints
x=-2, y=2
x=-1, y=1
x=-1, y=2
x=0, y=1
x=0, y=2
x=0, y=3
x=1, y=1
x=1, y=2
x=1, y=3
x=2, y=2
Note: the length of the encoding String doesn't add any byte code!.
When you run the first code it actually creates the array and each element at runtime. There is no compile time optimisation. I suggest you check whether and why your getSensorLocs method is slower because it shouldn't be significantly slower.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With