JDK-6501204 : (cal) Performance degradation in Calendar since upgrading from jdk 1.4.2 to 1.5.09
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Affected Version: 5.0
  • Priority: P3
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2006-12-06
  • Updated: 2011-02-16
  • Resolved: 2006-12-07
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.5.0_09"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_09-b03)
Java HotSpot(TM) Server VM (build 1.5.0_09-b01, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
windows xp, aix, solaris

A DESCRIPTION OF THE PROBLEM :
since upgrading to jdk 1.5, we are seeing performance problems in our application. initial jvm profiling indicates the problem may be with the java.util.Calendar and java.util.GregorianCalendar classes.  our code makes extensive use of these classes and the time taken is now 2-3 times slower.

This has been replicated in all versions of jdk1.5.0, including the latest 1.5.0_10.

I've looked into sun's source code for the Calendar class and I think I've identified the source of the performance degradation.

The calendar class uses two internal representations of time: one in milliseconds, and the other using the calendar fields like DAY, MONTH, YEAR, etc. Calling the set method on the calendar class causes these two to go out of synch. In jdk 1.5, whenever before, after, or equals is called and the milliseconds and calendar fields are not in sync, a new calendar object is cloned and instead of doing a milliseconds compare.  also, it does not sync the values so subsequent calls will also clone a new
calendar object. Is there any reason why they don't re-compute the milliseconds and calendar fields when the comparison methods are called like they are in jdk 1.4?  

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run CalendarCompare.bat. It needs to be modified to point to the correct
directories on your local machine.

EXPECTED VERSUS ACTUAL BEHAVIOR :
ACTUAL -
Below is the output that demonstrates how not calling getTime() before
the before, equals, and equals methods results in a significant
performance decrease in jdk 1.5. 

Calling getTime()
Java vendor=Sun Microsystems Inc., version=1.3.1_15
Calendar.set()    took  592
Calendar.get()    took  3047
Calendar.before() took  597
Calendar.after()  took  457
Calendar.equals() took  625
                  TOTAL 6531

Java vendor=Sun Microsystems Inc., version=1.4.2_10
Calendar.set()    took  220
Calendar.get()    took  4113
Calendar.before() took  688
Calendar.after()  took  463
Calendar.equals() took  346
                  TOTAL 7281

Java vendor=Sun Microsystems Inc., version=1.5.0_05
Calendar.set()    took  77
Calendar.get()    took  5660
Calendar.before() took  48
Calendar.after()  took  218
Calendar.equals() took  308
                  TOTAL 6968

Java vendor=Sun Microsystems Inc., version=1.5.0_09
Calendar.set()    took  206
Calendar.get()    took  4533
Calendar.before() took  142
Calendar.after()  took  107
Calendar.equals() took  234
                  TOTAL 5875

Java vendor=IBM Corporation, version=1.5.0
Calendar.set()    took  453
Calendar.get()    took  4080
Calendar.before() took  1314
Calendar.after()  took  1018
Calendar.equals() took  827
                  TOTAL 9594

Without calling getTime()
Java vendor=Sun Microsystems Inc., version=1.3.1_15
Calendar.set()    took  372
Calendar.get()    took  172
Calendar.before() took  2013
Calendar.after()  took  378
Calendar.equals() took  395
                  TOTAL 4969

Java vendor=Sun Microsystems Inc., version=1.4.2_10
Calendar.set()    took  480
Calendar.get()    took  264
Calendar.before() took  2927
Calendar.after()  took  390
Calendar.equals() took  609
                  TOTAL 6062

Java vendor=Sun Microsystems Inc., version=1.5.0_05
Calendar.set()    took  296
Calendar.get()    took  110
Calendar.before() took  9976
Calendar.after()  took  9471
Calendar.equals() took  9710
                  TOTAL 30218

Java vendor=Sun Microsystems Inc., version=1.5.0_09
Calendar.set()    took  232
Calendar.get()    took  78
Calendar.before() took  10170
Calendar.after()  took  9324
Calendar.equals() took  10023
                  TOTAL 30437

Java vendor=IBM Corporation, version=1.5.0
Calendar.set()    took  342
Calendar.get()    took  269
Calendar.before() took  8395
Calendar.after()  took  8982
Calendar.equals() took  10475
                  TOTAL 30171

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
Attached Seperatly
---------- END SOURCE ----------

Comments
EVALUATION This is a know side effect of the fixes for 4080631, 4340146, and 4722650. I don't see any way to fix all of them with no performance impacts.
07-12-2006