My goal is to write a framework for measuring method execution or transaction time and for processing the measurements, i.e. storing, analysis etc. Transaction may include calls to external systems, with synchronously or asynchronously waiting for the results.
There already have been some questions around that topic, like
- "How do I time a method's execution"
- "Measure execution time for a Java method"
- "System.currentTimeMillis vs System.nanoTime"
And all the answers boil down to three approaches for taking the time
System.currentTimeMillis()
System.nanoTime()
Instant.now()
andDuration
(since Java 8)
I know, all of these have some implications
System.currentTimeMillis()
The result of this method depends on the platform. On Linux you get 1ms resolution, of Windows you get 10ms (single core) ~15ms (multi core). So it's ok for measuring large running operations or multiple executions of short running ops.
System.nanoTime()
You get a high resolution time measure, with nano second precision (but not necessarily nano second accuracy) and you get an overflow after 292 years (I could live with that).
Instant.now() and Duration
Since Java 8 there is the new time API. An instant has a second and a nano second field, so it uses on top of the Object reference two long values (same for Duration
). You also get nano second precision, depending on the underlying clock (see "Java 8 Instant.now() with nanosecond resolution?"). The instantiaion is done by invoking Instant.now()
which maps down to System.currentTimeMillis()
for the normal System clock.
Given the facts, it becomes apparent, that best precision is only achievable with System.nanoTime()
, but my question targets more towards a best-practice for dealing with the measures in general, which not only includes the measure taking but also the measure handling.
Instant and Duration provide best API support (calculating, comparing, etc) but have os-dependend precision in standard case, and more overhead for memory and creating a measure (Object construction, deeper callstack)
System.nanoTime() and System.currentTimeMillis() have different levels of precision but only have basic "api" support (math operations on long), but are faster to get and smaller to keep in memory.
So what would be the best approach? Are there any implications I didn't think of? Are there any alternatives?