3

I currently do this to successfully get the current epoch time in nanos:

Instant inst = Instant.now();
long time = inst.getEpochSecond();
time *= 1000000000l;
time += inst.getNano();

However, it's a bit too slow for my use case, taking around 1us each call after the JVM has warmed up.

Is there a faster way to do it?

I'm happy with a solution that gives me the microseconds since epoch, as long as it's faster than the above.

ABC
  • 693
  • 1
  • 10
  • 22
  • Most computer hardware can't measure time in nano seconds. – Johannes Kuhn Oct 09 '19 at 10:23
  • @JohannesKuhn I'm happy with a solution that gives me the microseconds instead of nanoseconds. – ABC Oct 09 '19 at 10:26
  • You'd probably need to dip into native code for a high performance timer. The `Instant` approach is bound to be slow and results may vary. What are you using these values for? – Kayaman Oct 09 '19 at 10:29
  • Did you try with System.currentTimeMillis() – Mohinuddin Luhar Oct 09 '19 at 10:32
  • @MohinuddinLuhar I need micros resolution – ABC Oct 09 '19 at 10:35
  • @Kayaman I'm using them inside my trading system to drive decision making, logging, etc. If I can save `0.2us` on the calculation I'd be very happy. – ABC Oct 09 '19 at 10:35
  • See [here](https://stackoverflow.com/questions/40250112/fastest-way-to-measure-elapsed-time-in-java) for some related information. You might be better off combining `System.currentTimeMillis()` and `System.nanoTime()` if you can. They're intrinsics, so they should give you a noticeable performance boost. – Kayaman Oct 09 '19 at 10:39
  • Can you check https://stackoverflow.com/questions/351565/system-currenttimemillis-vs-system-nanotime – Mohinuddin Luhar Oct 09 '19 at 10:44
  • @Kayaman `Instant.now()` is internally doing exactly that, i.e. combining `System.currentTimeMillis()` and `System.nanoTime()`. The only thing you'd gain by trying to do it yourself, is eliminate the need to create an `Instant` object. – Andreas Oct 09 '19 at 11:31
  • @Andreas indeed, that was my point, not to mention going through the `Clock` class. Although whether bypassing that is faster than the JIT optimized version remains to be seen. – Kayaman Oct 09 '19 at 11:33

1 Answers1

0

What may work is to run:

long n1 = System.nanoTime();
long m = System.currentTimeMillis();
long n2 = System.nanoTime();

a number of times until the difference between n1 and n2 is less than the resolution you want (it's about 400 ns on my PC after a couple of iterations).

You can then use the difference between n1 (or n2 or an average of the 2...) and m * 1e6 as an offset that you need to add to System.nanoTime() to get the current epoch nanos.

Disclaimer:

  • System.nanoTime doc explicitly states that the resolution is at least that of System.currentTimeMillis(), which may be > 1 ms. So no guarantee that you will get microsecond resolution.
  • Corollary: this probably doesn't work in all environments (you may never get n2-n1 small enough - or it may be 0 just because the resolution of your system is too low).
  • System.nanoTime() may be out of sync over long periods - so this is a trade off between precision and performance.
  • You also need to account for possible arithmetic overflow.

See also: Current time in microseconds in java

assylias
  • 321,522
  • 82
  • 660
  • 783