-
Bug
-
Resolution: Won't Fix
-
P4
-
None
-
1.4.2
-
x86
-
windows_2000
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 ----------
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 ----------
- relates to
-
JDK-4340146 Calendar.equals modifies state
-
- Resolved
-