Easy to use Java stopwatch allowing measurement of elapsed time.
- The same task can be timed multiple times for aggregated/cumulative data.
- Supports numerous metrics:
- mean
- median
- min/max
- max
- standard deviation
- percentiles
- percentage
- count
- total time
- Human-readable durations
- Highly tweaked code for minimal overhead. Custom list for capturing results with as low overhead as possible.
- Dynamic ASCII/UTF-8 table support for detailed result output on the console or in logs
- Support for colored output (ANSI console)
- Easy to fetch the underlying data for when you need your own output format
- Configurable sample interval for very fast running tasks
- No dependencies (~35KB jar file)
<dependency>
<groupId>com.ethlo.time</groupId>
<artifactId>chronograph</artifactId>
<version>1.2.0</version>
</dependency>
final Chronograph chronograph = Chronograph.create();
chronograph.start("my-task");
// perform a task
chronograph.stop();
System.out.printn(chronograph.prettyPrint());
final List<Long> myList = ...;
final Chronograph chronograph = Chronograph.create();
chronograph.timed("List sort", () -> linkedList.sort(Comparator.naturalOrder()));
System.out.printn(chronograph.prettyPrint());
Empty columns will be dropped automatically. Included columns can be configured.
Begin from scratch:
final OutputConfig cfg = new OutputConfig()
.median(true)
.standardDeviation(true));
Begin from DEFAULT configuration:
final OutputConfig cfg = Chronograph.configure(OutputConfig.DEFAULT
.percentiles(75, 90, 99, 99.9, 99.99));
Output TSV (Tab separated values) with throughput per second values (instead of duration)
System.out.println(Report.prettyPrint(chronograph,
OutputConfig.COMPACT
.mode(PresentationMode.THROUGHPUT)
.benchmarkMode(true)
.formatting(false),
TableTheme.TSV
// Then use it like this
System.out.println(chronograph.prettyPrint(cfg, TableTheme.RED_HERRING);
If you run very quick tasks (typically less than milliseconds) in a loop, it may be beneficial to not capture every iteration, but instead sample some of them. This can be achieved by
final Chronograph chronograph = Chronograph
.create(CaptureConfig
.minInterval(Duration.ofNanos(10_000))); // 10 microseconds
You can choose to output the results using different styles and colors. Below are a few examples.
final Chronograph chronograph = Chronograph.create();
final OutputConfig cfg = ...;
System.out.println(chronograph.prettyPrint(cfg, TableTheme.RED_HERRING));
final TableTheme myTheme = TableTheme.builder()
.stringColor(AnsiColor.BLUE)
.numericColor(AnsiColor.GREEN)
.horizontalSeparator(" ")
.verticalSpacerColor(AnsiColor.GRAY)
.horizontalSpacerColor(AnsiColor.GRAY)
.build();
This project is utilizing System.nanoTime()
which has some inherent issues with very quick task times. It does have a nanosecond resolution, but not a nanosecond precision. These are still usually orders of magnitude away from what you are trying to measure, so it is not a problem. If you are micro-benchmarking, consider using a framework like JMH.
If you would like to know more:
- https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/System.html#nanoTime()
- https://shipilev.net/blog/2014/nanotrusting-nanotime/#_timers
The Chronograph is NOT thread safe.