User:Jdev/Code/TimeProfiler
From RoboWiki
It's utility class for robots time profiling. Feel free to adopt and/or use it
Code:
package lxx.utils.time_profiling; import lxx.utils.ValueInfo; import static java.lang.StrictMath.max; public enum TimeProfile { TURN_TIME; private ValueInfo battleProfile; private ValueInfo roundProfile; private ValueInfo turnProfile; private long startTime = -1; public void start() { if (startTime != -1) { System.out.printf("[WARN] %s: Stop was not called\n", this.name()); return; } startTime = System.nanoTime(); } public void stop() { if (startTime == -1) { System.out.printf("[WARN] %s: Start was not called\n", this.name()); return; } final long time = System.nanoTime() - startTime; battleProfile.addValue(time); roundProfile.addValue(time); turnProfile.addValue(time); startTime = -1; } public static void initBattle() { for (TimeProfile tp : values()) { tp.battleProfile = new ValueInfo(1500000); } } public static void initRound() { for (TimeProfile tp : values()) { tp.roundProfile = new ValueInfo(60000); } } public static void initTurn() { for (TimeProfile tp : values()) { tp.turnProfile = new ValueInfo(300); } } public static String getBattleProfilesString() { final StringBuilder res = new StringBuilder(" == Battle Time Profiles == \n"); int maxPropertyNameLength = getMaxNameLen(); for (TimeProfile tp : values()) { res.append(" ").append(String.format("%" + maxPropertyNameLength + "s", tp.name())).append(": ").append(tp.battleProfile.toString()).append("\n"); } return res.toString(); } public static String getRoundProfilesString() { final StringBuilder res = new StringBuilder(" == Round Time Profiles == \n"); int maxPropertyNameLength = getMaxNameLen(); for (TimeProfile tp : values()) { res.append(" ").append(String.format("%" + maxPropertyNameLength + "s", tp.name())).append(": ").append(tp.roundProfile.toString()).append("\n"); } return res.toString(); } public static String getTurnProfilesString() { final StringBuilder res = new StringBuilder(" == Turn Time Profiles == \n"); int maxPropertyNameLength = getMaxNameLen(); for (TimeProfile tp : values()) { res.append(" ").append(String.format("%" + maxPropertyNameLength + "s", tp.name())).append(": ").append(tp.turnProfile.toString()).append("\n"); } return res.toString(); } private static int getMaxNameLen() { int maxNameLen = 0; for (TimeProfile tp : values()) { maxNameLen = max(maxNameLen, tp.name().length()); } return maxNameLen; } } package lxx.utils; import static java.lang.Math.max; import static java.lang.StrictMath.min; public class ValueInfo { private final AvgValue avgValue; private double maxValue = Long.MIN_VALUE; private double minValue = Long.MAX_VALUE; private double total; public ValueInfo(int deph) { avgValue = new AvgValue(deph); } public void addValue(double value) { maxValue = max(maxValue, value); minValue = min(minValue, value); avgValue.addValue(value); total += value; } @Override public String toString() { if (maxValue == Long.MIN_VALUE) { return "[ No Data ]"; } else if (maxValue == minValue) { return String.format("[ %,14.0f ]", minValue); } else { return String.format("[ %,9.0f | %,9.0f | %,14.0f | %,20.0f]", minValue, avgValue.getCurrentValue(), maxValue, total); } } } package lxx.utils; import static java.lang.Math.min; public class AvgValue { private final double[] values; private final int depth; private int valuesCount; private double currentSum; private double currentValue; public AvgValue(int depth) { this.depth = depth; values = new double[depth]; } public void addValue(double newValue) { currentSum = currentSum - values[valuesCount % values.length] + newValue; values[valuesCount % values.length] = newValue; valuesCount++; currentValue = currentSum / min(valuesCount, depth); } public double getCurrentValue() { return currentValue; } public String toString() { return String.format("Avg value = %10.5f", getCurrentValue()); } }
Usage (typed in browser, so may contains errors):
public class TPRobot extends AdvancedRobot { static { TimeProfile.initBattle(); } public void run() { TimeProfile.initRound(); while (true) { TimeProfile.initTurn(); TimeProfile.TURN_TIME.start(); // robot code TimeProfile.TURN_TIME.stop(); execute(); } } public void onDeath(DeathEvent event) { System.out.println(TimeProfile.getRoundProfilesString()); System.out.println(TimeProfile.getBattleProfilesString()); } public void onWin(WinEvent event) { System.out.println(TimeProfile.getRoundProfilesString()); System.out.println(TimeProfile.getBattleProfilesString()); } public void onSkippedTurn(SkippedTurnEvent event) { System.out.println(TimeProfile.getTurnProfilesString()); } }
Output example:
== Round Time Profiles == TURN_TIME: [ 31 451 | 720 724 | 33 814 642 | 1 457 304 116] PROCESS_LISTENERS_TIME: [ 24 830 | 339 116 | 33 614 018 | 685 691 651] EBM_WAVE_TIME: [ 556 183 | 1 763 225 | 32 754 914 | 297 984 994] SELECT_ORBIT_DIRECTION_TIME: [ 54 956 | 391 181 | 1 212 348 | 362 233 454] GUN_TIME: [ 1 524 870 | 1 916 700 | 3 495 349 | 327 755 712] TR_RANGE_SEARCH_TIME: [ 1 325 | 31 450 | 31 329 693 | 308 243 570] TR_SORT_TIME: [ 0 | 20 288 | 748 531 | 248 448 312] MOVEMENT_TIME: [ 2 980 | 212 053 | 1 720 527 | 428 347 163] == Battle Time Profiles == TURN_TIME: [ 9 269 | 524 517 | 36 706 135 | 28 108 844 538] PROCESS_LISTENERS_TIME: [ 6 290 | 207 137 | 36 682 630 | 11 100 497 548] EBM_WAVE_TIME: [ 149 970 | 991 202 | 34 882 647 | 4 173 953 087] SELECT_ORBIT_DIRECTION_TIME: [ 14 567 | 388 092 | 33 676 920 | 9 231 536 613] GUN_TIME: [ 245 648 | 1 458 686 | 34 828 353 | 6 219 835 279] TR_RANGE_SEARCH_TIME: [ 331 | 17 518 | 35 778 500 | 4 177 437 515] TR_SORT_TIME: [ 0 | 11 702 | 3 681 737 | 3 044 313 750] MOVEMENT_TIME: [ 1 655 | 198 914 | 33 693 142 | 10 390 890 834]