Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6609279

(cal) GregorianCalendar methods before/equals/after have poor performance with JDK 1.5

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Won't Fix
    • Icon: P4 P4
    • None
    • 1.4.2
    • core-libs

      FULL PRODUCT VERSION :
      java version "1.5.0_04"

      ADDITIONAL OS VERSION INFORMATION :
      Windows 2000 SP4

      A DESCRIPTION OF THE PROBLEM :
      The methods "before", "equals" and "after" of class
      GregorianCalendar have a very poor performance when a program
      is run with JDK 1.5.0_04 instead of JDK 1.4.2_04.

      This behaviour was detected in a program used to build up
      a public traffic timetable which calls these methods
      several million times each. The problem was confirmed with the
      test program shown below which simply calls the methods
      one million times each. The output varies slightly from one
      run to another, but the order of magnitude of the difference
      remains the same (more than 100 times slower for 1.5.0).

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      run the program below with both 1.4.2_04 and 1.5.0_04

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      the 1.5 performance is on a par if not better than 1.4
      ACTUAL -
      the performance is *exceptionally* slower:

      Output for JDK 1.4.2_04:

      Starting test...
      Time (millisec) needed for 1000000 calls of GregorianCalendar.before(): 31
      Time (millisec) needed for 1000000 calls of GregorianCalendar.equals(): 63
      Time (millisec) needed for 1000000 calls of GregorianCalendar.after(): 47
      Test finished.


      Output for JDK 1.5.0_04:

      Starting test...
      Time (millisec) needed for 1000000 calls of GregorianCalendar.before(): 15891
      Time (millisec) needed for 1000000 calls of GregorianCalendar.equals(): 16063
      Time (millisec) needed for 1000000 calls of GregorianCalendar.after(): 15828
      Test finished.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      /**
       * Class to show poor behaviour of 1.5 compared to 1.4.
       * usage: java GregorianCalendarTest
       */

      import java.util.GregorianCalendar;

      public class GregorianCalendarTest {

      GregorianCalendar gc1 =
                                              new GregorianCalendar(1970, 1, 1);
      GregorianCalendar gc2 =
                                              new GregorianCalendar(1971, 1, 1);


      public static void main(String[] args) {
      GregorianCalendarTest gctest =
                                                       new GregorianCalendarTest();
      }

      public GregorianCalendarTest() {

      long calcStart = 0;
      long calcEnd = 0;

      int numberOfComparisons = 1000000;

      System.out.println("Starting test...");

      calcStart = System.currentTimeMillis();
      doBeforeCheck(numberOfComparisons);
      calcEnd = System.currentTimeMillis();
      System.out.println("Time (millisec) needed for " + numberOfComparisons +
      " calls of GregorianCalendar.before(): " + (calcEnd - calcStart));

      calcStart = System.currentTimeMillis();
      doEqualsCheck(numberOfComparisons);
      calcEnd = System.currentTimeMillis();
      System.out.println("Time (millisec) needed for " + numberOfComparisons +
      " calls of GregorianCalendar.equals(): " + (calcEnd - calcStart));

      calcStart = System.currentTimeMillis();
      doAfterCheck(numberOfComparisons);
      calcEnd = System.currentTimeMillis();
      System.out.println("Time (millisec) needed for " + numberOfComparisons +
      " calls of GregorianCalendar.after(): " + (calcEnd - calcStart));

      System.out.println("Test finished.");

      }

      private void doBeforeCheck(int ntimes) {
      for (int i=0; i<ntimes; i++) {
      gc1.before(gc2);
      }
      }
      private void doEqualsCheck(int ntimes) {
      for (int i=0; i<ntimes; i++) {
      gc1.equals(gc2);
      }
      }
      private void doAfterCheck(int ntimes) {
      for (int i=0; i<ntimes; i++) {
      gc1.after(gc2);
      }
      }
      }
      ---------- END SOURCE ----------

            okutsu Masayoshi Okutsu
            okutsu Masayoshi Okutsu
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: