Monday, May 9, 2022

Java Tutorial: currentTimeMillis() and nanoTime()

Chapters

currentTimeMillis() and nanoTime()

currentTimeMillis() returns the current time of our machine in milliseconds. The measured time starts from midnight, January 1, 1970 UTC (epoch time) up to the current date in our machine. Take note that the granularity of the value depends on the underlying operating system and may be larger. For example, many operating systems measure time in units of tens of milliseconds.

nanoTime() returns the current time of our machine in nanoseconds. The measured time starts from midnight, January 1, 1970 UTC (epoch time) up to the current date/time in our machine.

Take note that the method provides nanosecond precision, but not necessarily nanosecond resolution. This means that the returned value is in nanosecond digits but the returned value itself maybe larger than a nanosecond. The resolution of nanoTime() is at least as good as that of currentTimeMillis().

For high precision timers, use nanoTime(). Otherwise, currentTimeMillis() should suffice. These two methods can be found in the System class.

This example demonstrates currentTimeMillis().
public class SampleClass{

  public static void main(String[] args){
      long currentTime = System.currentTimeMillis();
      MyTimer timer = new MyTimer(
      currentTime, currentTime + 3000L);
      timer.start();
  }
}

class MyTimer extends Thread{
  long time = 0L;
  long initTime = 0L;
  
  MyTimer(long initTime, long time){
    this.initTime = initTime;
    this.time = time;
    
    System.out.println("Starting Time");
    System.out.println(initTime);
    System.out.println("Target Time");
    System.out.println(time);
    System.out.println();
  }
  
  @Override
  public void run(){
    long timeMillis = initTime;
    long targetTime = time;
    
    if(targetTime < timeMillis){
      System.out.println("Target time "+
      "is less than current time!");
      return;
    }
    
    while(timeMillis < targetTime){
      System.out.println("Remaining Time");
      System.out.println((targetTime - timeMillis) + 
      " milliseconds.");
      System.out.println(
      ((targetTime - timeMillis)/1000) + //convert millis to seconds
      " seconds.");
      System.out.println();
      
      try{ Thread.sleep(900L); }
      catch(InterruptedException e){
        e.printStackTrace();
      }
      timeMillis = System.currentTimeMillis();
    }
    System.out.println("\nDone!");
  }
}

Result(may vary)
Starting Time
1652089057223
Target Time
1652089060223

Remaining Time
3000 milliseconds.
3 seconds.

Remaining Time
2085 milliseconds.
2 seconds.

Remaining Time
1183 milliseconds.
1 seconds.

Remaining Time
280 milliseconds.
0 seconds.

Done!
In MyTimer constructor, initTime parameter is the starting time in our timer. We use System.currentTimeMillis() to get the current time once our program runs and use that as the starting time. time parameter is our target time, we use the current time plus additional milliseconds to get our desired target time.

In the example above, the distance between the starting time and target time is 3000 millis. Now, try to use nanoTime() instead of currentTimeMillis() in the example above.

currentTimeMillis() and nanoTime() have many uses. Another use of them is creating a basic performance test. Take a look at this example.
import java.util.Random;

public class SampleClass{

  public static void main(String[] args){
    Random random = new Random();
    
    System.out.println("StartTime");
    long startTime = System.nanoTime();
    System.out.println(startTime);
    
    double num = 0;
    for(int i = 0; i < 1000000; i++)
      num = i/random.nextInt();
    
    System.out.println("EndTime");
    long endTime = System.nanoTime();
    System.out.println(endTime);
    System.out.println();
    
    System.out.println("Elapsed Time");
    double elapsed = endTime - startTime;
    System.out.println(elapsed + " nanoseconds");
    //convert nano to millis
    //1000 nanosec = 1 microsec
    //1000 microsec = 1 millisec
    System.out.println(elapsed/1000/1000 + " milliseconds");
  }
}

Result(may vary)
1.3453649e7 nanoseconds
13.45364899 milliseconds

No comments:

Post a Comment