Stopwatch class for Java

Viewed 67547

Which Java class should you use for time performance measurements?

(One could use any date/time class, but the reason I'm asking is in .Net there's a designated Stopwatch class for this purpose)

10 Answers

The Spring Framework has an excellent StopWatch class:

StopWatch stopWatch = new StopWatch("My Stop Watch");

stopWatch.start("initializing");
Thread.sleep(2000); // simulated work
stopWatch.stop();

stopWatch.start("processing");
Thread.sleep(5000); // simulated work
stopWatch.stop();

stopWatch.start("finalizing");
Thread.sleep(3000); // simulated work
stopWatch.stop();

System.out.println(stopWatch.prettyPrint());

This produces:

    StopWatch 'My Stop Watch': running time (millis) = 10000
    -----------------------------------------
    ms     %     Task name
    -----------------------------------------
    02000  020%  initializing
    05000  050%  processing
    03000  030%  finalizing

Performetrics provides a convenient Stopwatch class. It can measure wall-clock time and more: it also measures CPU time, user time and system time, if you need more accuracy. It's small, free and you can download from Maven Central. More information and examples can be found here: https://obvj.net/performetrics

Stopwatch sw = new Stopwatch();
sw.start();

// Your code here

sw.stop();
sw.printStatistics(System.out);

This produces an output similar to the following:

+-----------------+----------------------+--------------+
| Counter         |         Elapsed time | Time unit    |
+-----------------+----------------------+--------------+
| Wall clock time |             85605718 | nanoseconds  |
| CPU time        |             78000500 | nanoseconds  |
| User time       |             62400400 | nanoseconds  |
| System time     |             15600100 | nanoseconds  |
+-----------------+----------------------+--------------+

You can convert the metrics to any time unit (nanoseconds, milliseconds, seconds, etc...) just by passing a custom parameter.

PS: I am the author of the tool.

If you are using JDK 9+, you could use Flight Recorder. It has extremely low overhead and uses invariant TSC for timing, which is less intrusive than System.nanoTime()

@StackTrace(false)
static class StopWatch extends Event {
  int fib;
}

public static void main(String... args) throws IOException {
    Recording r = new Recording();
    r.start();
    for (int i = 0; i < 500000; i++) {
        StopWatch s = new StopWatch();
        s.begin();
        s.fib = fib(i%100);
        s.commit();
    }
    r.stop();
    Path p = Paths.get("recording.jfr");
    r.dump(p);
    for (RecordedEvent e : RecordingFile.readAllEvents(p)) {
        System.out.println(e.getValue("fib") + " " + e.getDuration().toNanos() + " ns");
    }
}

You can also start a recording from command line (-XX:StartFlightRecording) and then enable the event in a configuration file (.jfc) (if you disable it by default, @Enable(false))

That way the JIT will typically optimize away the StopWatch calls (escape analysis, inlining, deadcode elimination etc), so you only pay the penalty when you want to measure something.

Related