Skip to content

ethlo/chronograph

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

90 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Chronograph

Maven Central Hex.pm Codacy Badge

Easy to use Java Chronograph (stopwatch) allowing measurement of elapsed time.

Features

  • 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)

Getting started

Include in your project

Maven coordinates

<dependency>
  <groupId>com.ethlo.time</groupId>
  <artifactId>chronograph</artifactId>
  <version>1.2.0</version>
</dependency>

Usage

Simple

final Chronograph chronograph = Chronograph.create();
chronograph.start("my-task");
// perform a task
chronograph.stop();
System.out.printn(chronograph.prettyPrint());

Functional style with lamda

final List<Long> myList = ...;
final Chronograph chronograph = Chronograph.create();     
chronograph.timed("List sort", () -> linkedList.sort(Comparator.naturalOrder()));
System.out.printn(chronograph.prettyPrint());

Choice of output columns

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);

Reduced sample interval

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

Themes

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));

Themes

Make your own

final TableTheme myTheme = TableTheme.builder()
    .stringColor(AnsiColor.BLUE)
    .numericColor(AnsiColor.GREEN)
    .horizontalSeparator(" ")
    .verticalSpacerColor(AnsiColor.GRAY)
    .horizontalSpacerColor(AnsiColor.GRAY)
    .build();

Limitations

Time resolution

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:

Thread safety

The Chronograph is NOT thread safe.

About

Highly configurable, easy to use stopwatch allowing measurement of accumulated run-time, with support for numerous statistics.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages