Java System.nanoTime() vs System.currentTimeMillis


Java provides two methods to time operations, System.nanoTime() and System.currentTimeMillis(). But which one should be used in which condition? And which is more efficient?

From the first look it might seem that nanoTime() should be used because it gives more precise value of time (in nano seconds, compared to milli seconds that the other method returns). But is it always efficient on the CPU to use nanoTime? Let us look at pros and cons of using both the methods:

System.currentTimeMillis()

public static long currentTimeMillis()
// Returns the current time in milliseconds.

Pros:

  1. It is thread safe. Thread safety means that if this method is called between two or more different threads, it will not return erroneous results.
  2. Always returns the absolute time elapsed since the epoch (number of millis since 1 Jan 1970 00:00).
  3. Consumes lesser clock cycles to execute (around 5-6 cpu clocks).
  4. Gives more accurate time, since the point of reference (the epoch) is fixed.

Cons:



  1. Less precise. The result is somewhere between 1/1000th to 15/1000th of a second. On some machines, the resolution is even less than 50ms and can go down to upto 10ms only.
  2. It may give wrong results if the user changes the system time, hits a leap second or there are changes in NTP sync.

System.nanoTime()

public static long nanoTime()
// Returns the current value of the running JVM's high-resolution
// time source, in nanoseconds.

Pros:

  1. Highly precise. The time returned is around 1/1000000th of a second.
  2. The resolution is much higher than currentTimeMillis().

Cons:

  1. The result reflected doesn’t have any fixed reference point. According to Java documentation,
    The value returned represents nanoseconds since some fixed
    but arbitrary time (perhaps in the future, so values may be negative).
  2. Less accurate. This method provides nanosecond precision, but not necessarily nanosecond accuracy. No guarantees are made about how frequently values change.
  3. Depending on the system, it can take more than 100 cpu cycles to execute.
  4. Not thread safe. May return erroneous results if used between more than one threads.

Let’s see a working example to compare the results of these two functions:

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to illustrate
// difference between
// Java System.nanoTime()
// and System.currentTimeMillis
class Main {
    public static void main(String[] args)
    {
        // Get the current system time in
        // both nano and milli-seconds before
        // calling the function.
        long nano_startTime = System.nanoTime();
        long millis_startTime = System.currentTimeMillis();
  
        // Perform the work whose time is to be measured
        someFunction();
  
        // Get the current system time in both
        // nano and milli-seconds after
        // the function returns.
        long nano_endTime = System.nanoTime();
        long millis_endTime = System.currentTimeMillis();
  
        // Print the time taken by subtracting
        // the end-time from the start-time
        System.out.println("Time taken in nano seconds: "
                           + (nano_endTime - nano_startTime));
        System.out.println("Time taken in milli seconds: "
                           + (millis_endTime - millis_startTime));
    }
  
    // The function whose execution
    // time is to be measured
    public static void someFunction()
    {
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            for (int j = 0; j < Integer.MAX_VALUE; j++) {
                // Here for example purpose
                // we run an empty loop
            }
        }
    }
}

chevron_right


Output:

Time taken in nano seconds: 2519657
Time taken in milli seconds: 3

In conclusion, System.nanoTime() can/must be used whenever tasks of high precisions are to be performed, because it might seem that milli seconds is enough precision but for applications requiring fast performances (like games) nanoTime() will give much better results.
However, it should be avoided whenever possible due to computational overheads and risks related to thread safety, in which case currentTimeMillis() is to be used.

Attention reader! Don’t stop learning now. Get hold of all the important Java and Collections concepts with the Fundamentals of Java and Java Collections Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :
Practice Tags :


1


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.