Timing Java Code
Suppose one is interested in timing a piece of code and suppose that wall clock time, as opposed to actual CPU time, is adequate. In Java, this is easy using a class like Stopwatch:
//Time-stamp: <2011-04-24 19:37:57 jdm>
public class Stopwatch {
private long t0; // time that Stopwatch was started
public Stopwatch() {
restart();
}
// resets the Stopwatch to zero
public final synchronized void restart() {
t0 = System.currentTimeMillis();
}
// returns elapsed time in seconds
public final synchronized double read() {
long tnow = System.currentTimeMillis() - t0;
return tnow / 1000.0;
}
// Returns elapsed time in seconds
public final synchronized double elapsedS() {
return read();
} // elapsedS()
// Returns elapsed time in milliseconds.
public final synchronized long elapsedMs() {
return System.currentTimeMillis() - t0;
} // elapsedMs()
} // Stopwatch class
To use a Stopwatch, first create a Stopwatch instance at the point where the timing should begin. Then, to read the Stopwatch, call elapsedS() for the elapsed time in seconds, or elapsedMs() for elapsed time in milliseconds. To restart the timer, call restart() or simply create a new Stopwatch.
A typical application of Stopwatch:
Stopwatch timer = new Stopwatch();
f(); // a method to be timed
double elapsedSeconds = timer.elapsedS();
timer.restart();
g(); // a second method to be timed
long elapsedMilliseconds = timer.elapsedMs();
For an example use of Stopwatch, look at Zero.java below:
//Time-stamp: <2011-04-24 21:34:40 jdm>
public class Zero {
public static void main(String[] args) {
final int n = Integer.parseInt(args[0]);
long count = 0;
System.out.println("Starting...");
Stopwatch clock = new Stopwatch();
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
++count;
System.out.println("Finished after "
+ clock.read()
+ " seconds.");
//System.out.println(count);
} // main()
} // class Zero
Notice that the output of count is commented-out in the code just presented. Why? Usually the Java compiler performs some simple optimizations of generated code, and the compiler can see that count is never actually used after the loop. Thus, the compiler removes the increment of count from the loop. But, without that increment, the loop does nothing, so the loop is removed as well.
When I run this version of Zero, the run time is below 0.01s regardless of the size of n. When I uncomment the output line, I see times like these:
| n | Time |
| 1000 | 0.005 seconds |
| 10000 | 0.013 seconds |
| 100000 | 0.631 seconds |
| 1000000 | 65.05 seconds |
Increasing n by another factor of ten would likely result in a run time about 100 times as long, or roughly 6500 seconds, which is well over an hour.
A moral here is that when timing loops, it may be necessary to make sure the loop actually does something.