Explain Codes LogoExplain Codes Logo

System.currenttimemillis vs System.nanoTime

java
benchmarking
performance
best-practices
Alex KataevbyAlex Kataev·Dec 1, 2024
TLDR

Opt for System.currentTimeMillis() when your need is to trace real-world calendar time, with accuracy up to milliseconds. However, if your task involves measuring performance over short intervals demanding high-resolution timing, turn to System.nanoTime(), unaffected by the real "wall-clock" time.

  • System.currentTimeMillis(): Useful for dealing with calendar dates and timestamps

  • System.nanoTime(): Handy for timing code execution duration and performance benchmarks

// Timekeepers, start your stopwatches! 👟 long start = System.nanoTime(); // Some serious code business happening here 💼... long timeTaken = System.nanoTime() - start; // Who knew time could fly by in nano seconds! 🤸‍♂️

Note: System.nanoTime() is your best bet for interval timing, not for the real-time date/time.

Practical uses and considerations

The quick answer aids in basic decision making, yet the choice between System.currentTimeMillis() and System.nanoTime() can have significant implications, highly dependent upon your application specifics.

High-Resolution Timing

For situations demanding very short duration measurements, such as benchmarking or dealing with high-frequency trading algorithms, System.nanoTime() provides the required precision. With only 50ms default timing resolution on a Windows platform, System.currentTimeMillis() may prove insufficient for needs like animation or game object movement.

Consecutive Interval Measurements

System.nanoTime() is exclusively intended for measuring elapsed time, due to its monotonically increasing nature. Monotonic simply means the values are consistent and increasing without backward lapses, making nanoTime() perfect for interval timing, because it’s unaffected by any system clock adjustments or daylight saving changes.

Timing in Distributed Systems

In a distributed system with multiple JVMs, possibly across several systems, and where synchronized time-sensitive operations are required, System.currentTimeMillis() would be optimal as it reflects the universal wall clock time across JVMs (given they are time synchronized properly using utilities like Meinberg NTP client).

Be Wary of the Caveats

While System.nanoTime() offers enticing precision, older JVMs might not support this function, necessitating a resort to System.currentTimeMillis() or alternative solutions, such as GAGETimer, for improved accuracy. Remember, System.currentTimeMillis() is vulnerable to system time changes that can affect your time-critical operations.

Deep Dive into System Timing

Let's journey beyond the basics to study the broader implications of system timing strategies, providing practical examples and important considerations.

Game Loop Accuracy

In a game loop where objects move based on passed time, System.nanoTime() ensures consistent proportional-to-real-time movement, avoiding the pitfalls of lag or speed-up due to system time adjustments.

Beware of Benchmarking Traps

If conducting performance benchmarking, System.nanoTime() provides high precision, whereas System.currentTimeMillis() may overlook sub-millisecond execution alterations. Nevertheless, don't overlook the potential impacts of warm-up runs and JVM optimizations on your benchmarks.

Certain Java API calls, such as Thread.sleep(), interface with the system's clock, affecting Java's timing resolution. As System.nanoTime() focuses on providing precise elapsed time measurements, actual timings might bear the influence of these APIs' granularity.

Have a Handle on Value Variation Frequency

Whilst System.nanoTime() promises nanosecond precision, the frequency at which the values change may fall short of offering a new discrete value every single nanosecond, due to limitations in hardware or JVM implementation. This primarily influences elapsed time computation, not calendar time determination.