Search code examples
javaperformancedatezoneddatetimejava.util.calendar

java.time.ZonedDateTime Vs java.util.Calendar performance check


I was trying to get month value. But I wanted to check which is better, java.util or java.time to retrieve month value. This is my code to check performance of Calender vs ZonedDateTime.

    //import java.time.Instant;
    //import java.time.ZonedDateTime;
    //import java.util.Calendar;

    Instant instant, instant2; 
    String diff;

    instant = Instant.now();
    int month2 = Calendar.getInstance().get(Calendar.MONTH) + 1;
    instant2 = Instant.now();
    diff = String.valueOf(instant2.getNano() - instant.getNano());
    System.out.println("month value " + month2 + "at: " + diff);

    instant = Instant.now();
    int month1 = ZonedDateTime.now().getMonth().getValue();
    instant2 = Instant.now();
    diff = String.valueOf(instant2.getNano() - instant.getNano());
    System.out.println("month value " + month1 + "at: " + diff);

I thought java.time was better than java.util. Hence I was expecting ZonedDateTime to perform better than Calendar. But here I found the inverse. My result was:

month value 6at: 0  //Calendar
month value 6at: 9000000 //ZonedDateTime

Any ideas why this is happening. And any suggestion on why I should thus use java.util.Calender instead of java.timeZonedDateTime.

P.S. I even reversed retrieving month2 after month1 as:

    Instant instant, instant2; 
    String diff;

    instant = Instant.now();
    int month1 = ZonedDateTime.now().getMonth().getValue();
    instant2 = Instant.now();
    diff = String.valueOf(instant2.getNano() - instant.getNano());
    System.out.println("month value " + month1 + "at: " + diff);

    instant = Instant.now();
    int month2 = Calendar.getInstance().get(Calendar.MONTH) + 1;
    instant2 = Instant.now();
    diff = String.valueOf(instant2.getNano() - instant.getNano());
    System.out.println("month value " + month2 + "at: " + diff);

Still same:

month value 6at: 8000000   //ZonedDateTime
month value 6at: 0  //Calendar

Solution

  • The design goals of java.time included clear and expected behaviour, immutable objects, thread-safety, leveraging of standards, and a number of other points. The goals did not include performing faster than the old date-time classes including Calendar. Also, while I have heard numerous complaints about the old classes, I have heard no complaints that they performed too poorly.

    If the far superior design of the modern API in some cases costs a performance penalty, I don’t think that we should be surprised nor worried.

    Your measurements are not trustworthy, though. Doing a correct benchmarking is more complicated than that. I did a few untrustworthy measurements too: On my computer I just got 124 178 930 nanos for Calendar and 66 794 865 for ZonedDateTime, about half, using System.nanoTime() for measurements. YearMonth.now().getMonthValue() (also from java.time) performed in just 8 339 306, about one 15th (1/15) of Calendar.

    The fact alone that for Calendar you have to add 1 to the month value and the reader needs to understand why you add 1, is a lot more important than performance, for 99.5 % of cases.

    Of course, if in your particular system you have a performance bottleneck and trustworthy measurements tell you that switching one of your methods to using Calendar, Time4J, Joda-Time, some Apache library or some C code will solve that problem, it’s a fully valid reason for doing so. I have a hard time imagining that it will be the case, but then again, I don’t know all computer systems in the world.

    Links