Java tutorial
/** * Profiler.java Created Aug 14, 2006 by Andrew Butler, PSL */ //package prisms.util; /** * A class that allows a programmer to determine the amount of time spend doing * certain routines */ public final class Profiler { /** * The static instance of Profiler, for ease of use */ public static final Profiler P = new Profiler("Main"); private String theName; private String[] theRoutines; private long[] theRoutineStartTimes; private long[] theRoutineProfiles; private int[] theCallCounts; /** * Creates a profiler * * @param name * The name for the profiler */ public Profiler(String name) { theName = name; clearSession(); } /** * Starts a profiling session */ public void startSession() { if (theRoutineStartTimes[0] >= 0) throw new IllegalStateException("Profiler session \"" + theName + "\" is already running"); theRoutineStartTimes[0] = System.currentTimeMillis(); } /** * Stops the profiling session */ public void stopSession() { long time = System.currentTimeMillis(); for (int i = 0; i < theRoutines.length; i++) { if (theRoutineStartTimes[i] < 0) continue; theRoutineProfiles[i] += time - theRoutineStartTimes[i]; theRoutineStartTimes[i] = -1; } } /** * Removes all data from this Profiler, effectively starting over */ public void clearSession() { theRoutines = new String[] { "Other" }; theRoutineStartTimes = new long[] { -1 }; theRoutineProfiles = new long[] { 0 }; theCallCounts = new int[] { 0 }; } /** * @return A string report showing the amount of time spent in the various * routines since the session was cleared */ public String printReport() { StringBuffer ret = new StringBuffer("Profile \"" + theName + "\" Report:\n"); int i; for (i = 1; i < theRoutines.length; i++) { ret.append(printProfile(i)); ret.append('\n'); } ret.append(printProfile(0)); ret.append('\n'); return ret.toString(); } private String printProfile(int i) { StringBuffer ret = new StringBuffer(theRoutines[i]); ret.append(": "); if (i > 0) { ret.append(theCallCounts[i]); ret.append(" calls: "); } int days, hrs, mins, secs, millis; long profile = theRoutineProfiles[i]; millis = (int) (profile % 1000); profile /= 1000; secs = (int) (profile % 60); profile /= 60; mins = (int) (profile % 60); profile /= 60; hrs = (int) (profile % 24); profile /= 24; days = (int) profile; if (days > 0) { ret.append(days); ret.append(" days "); } if (hrs > 0) { ret.append(hrs); ret.append(" hours "); } if (mins > 0) { ret.append(mins); ret.append(" minutes "); } if (secs > 0) { ret.append(secs); ret.append(" seconds "); } if (millis > 0) { ret.append(millis); ret.append(" millis"); } return ret.toString(); } /** * Notifies the profiler that a routine has started * * @param name * The name of the routine */ public void startRoutine(String name) { name = name.intern(); int i; for (i = 1; i < theRoutines.length && name != theRoutines[i]; i++) ; if (i == theRoutines.length) { String[] newRoutines = new String[i + 1]; System.arraycopy(theRoutines, 0, newRoutines, 0, i); newRoutines[i] = name; theRoutines = newRoutines; long[] longArray = new long[i + 1]; System.arraycopy(theRoutineStartTimes, 0, longArray, 0, i); longArray[i] = -1; theRoutineStartTimes = longArray; longArray = new long[i + 1]; System.arraycopy(theRoutineProfiles, 0, longArray, 0, i); longArray[i] = 0; theRoutineProfiles = longArray; int[] intArray = new int[i + 1]; System.arraycopy(theCallCounts, 0, intArray, 0, i); intArray[i] = 0; theCallCounts = intArray; } if (theRoutineStartTimes[i] >= 0) { stopRoutine(name); // throw new IllegalStateException("Routine " + name // + " already running: recursion not supported"); } long time = System.currentTimeMillis(); theRoutineStartTimes[i] = time; theCallCounts[i]++; if (theRoutineStartTimes[0] >= 0) { // Stop the "other" routine theRoutineProfiles[0] += time - theRoutineStartTimes[0]; theRoutineStartTimes[0] = -1; } } /** * Notifies the profiler that a routine has ended * * @param name * The name of the routine */ public void stopRoutine(String name) { name = name.intern(); int i; for (i = 1; i < theRoutines.length && name != theRoutines[i]; i++) ; if (i == theRoutines.length || theRoutineStartTimes[i] < 0) throw new IllegalStateException("Routine " + name + " is already finished or has not been started"); long time = System.currentTimeMillis(); theRoutineProfiles[i] += time - theRoutineStartTimes[i]; theRoutineStartTimes[i] = -1; for (i = 1; i < theRoutines.length && theRoutineStartTimes[i] < 0; i++) ; if (i == theRoutines.length) theRoutineStartTimes[0] = time; } }