FULL PRODUCT VERSION :
java version "1.5.0_01"
java version "1.4.2_06"
ADDITIONAL OS VERSION INFORMATION :
Windows 2000 SP4
EXTRA RELEVANT SYSTEM CONFIGURATION :
java -version
A DESCRIPTION OF THE PROBLEM :
StringBuffer.toString() optimizations have been removed in 1.5. This makes applications that repeadedly call sb.toString() on an large unchanged StringBuffer extreemly slow.
An example, we used to be able to parse and init a program in 600ms in 1.4.2 in 1.5 it takes over 4 minutes.
This is beacuse the char[] sharing in StringBuffer and String has been removed in 1.5 so the char[] is always copied, and not copied when modified, so for large strings (1 MB) with 10 toString()'s between modification of the buffer you have to copy 10 times the amount of data around! It would also appear to be a waste of memory as well as CPU.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
run the program below with both 1.4.2 and 1.5
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
the performance is on a par if not better than 1.4
ACTUAL -
the performance is *exceptionally* slower.
on a 2.4GHz P4 single CPU box 1.4 can call toString 10000000 times if the buffer has not been changed in the time that 1.5 can make less than 100 calls.
C:\sun>c:\java\jdk1.5.0_01\bin\java StringBufferTest 10
Starting test
stoped test
Duration of toString loop: 328 milliseconds
C:\sun>c:\java\jdk1.5.0_01\bin\java StringBufferTest 100
Starting test
stoped test
Duration of toString loop: 2969 milliseconds
C:\sun>c:\java\j2sdk1.4.2_06\bin\java.exe StringBufferTest 100
Starting test
stoped test
Duration of toString loop: 0 milliseconds
C:\sun>c:\java\j2sdk1.4.2_06\bin\java.exe StringBufferTest 10000
Starting test
stoped test
Duration of toString loop: 15 milliseconds
C:\sun>c:\java\j2sdk1.4.2_06\bin\java.exe StringBufferTest 100000
Starting test
stoped test
Duration of toString loop: 16 milliseconds
C:\sun>c:\java\j2sdk1.4.2_06\bin\java.exe StringBufferTest 10000000
Starting test
stoped test
Duration of toString loop: 1297 milliseconds
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
/**
* Class to show dumb behaviour of 1.5 compared to 1.4.
* usage java StringBufferTest <number of StringBuffer.toString() loops>
*/
public final class StringBufferTest {
public static void main(String[] args) {
int loops = Integer.parseInt(args[0]);
char[] eightChars = "01234567".toCharArray();
StringBuffer strB = new StringBuffer();
// simulate a large StringBuffer (eg an 0.5MB XML document) (UTF-8);
for (int i=0; i < (1024*1024/8); i++) {
strB.append(eightChars);
}
long start = 0;
long stop = 0;
String str = null;
System.out.println("Starting test");
start = System.currentTimeMillis();
for (int i=0; i < loops; i++) {
str = strB.toString();
}
stop = System.currentTimeMillis();
System.out.println("stoped test");
System.out.println("Duration of toString loop: " + (stop - start) + " milliseconds");
}
}
---------- END SOURCE ----------
###@###.### 2005-1-21 06:22:32 GMT
java version "1.5.0_01"
java version "1.4.2_06"
ADDITIONAL OS VERSION INFORMATION :
Windows 2000 SP4
EXTRA RELEVANT SYSTEM CONFIGURATION :
java -version
A DESCRIPTION OF THE PROBLEM :
StringBuffer.toString() optimizations have been removed in 1.5. This makes applications that repeadedly call sb.toString() on an large unchanged StringBuffer extreemly slow.
An example, we used to be able to parse and init a program in 600ms in 1.4.2 in 1.5 it takes over 4 minutes.
This is beacuse the char[] sharing in StringBuffer and String has been removed in 1.5 so the char[] is always copied, and not copied when modified, so for large strings (1 MB) with 10 toString()'s between modification of the buffer you have to copy 10 times the amount of data around! It would also appear to be a waste of memory as well as CPU.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
run the program below with both 1.4.2 and 1.5
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
the performance is on a par if not better than 1.4
ACTUAL -
the performance is *exceptionally* slower.
on a 2.4GHz P4 single CPU box 1.4 can call toString 10000000 times if the buffer has not been changed in the time that 1.5 can make less than 100 calls.
C:\sun>c:\java\jdk1.5.0_01\bin\java StringBufferTest 10
Starting test
stoped test
Duration of toString loop: 328 milliseconds
C:\sun>c:\java\jdk1.5.0_01\bin\java StringBufferTest 100
Starting test
stoped test
Duration of toString loop: 2969 milliseconds
C:\sun>c:\java\j2sdk1.4.2_06\bin\java.exe StringBufferTest 100
Starting test
stoped test
Duration of toString loop: 0 milliseconds
C:\sun>c:\java\j2sdk1.4.2_06\bin\java.exe StringBufferTest 10000
Starting test
stoped test
Duration of toString loop: 15 milliseconds
C:\sun>c:\java\j2sdk1.4.2_06\bin\java.exe StringBufferTest 100000
Starting test
stoped test
Duration of toString loop: 16 milliseconds
C:\sun>c:\java\j2sdk1.4.2_06\bin\java.exe StringBufferTest 10000000
Starting test
stoped test
Duration of toString loop: 1297 milliseconds
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
/**
* Class to show dumb behaviour of 1.5 compared to 1.4.
* usage java StringBufferTest <number of StringBuffer.toString() loops>
*/
public final class StringBufferTest {
public static void main(String[] args) {
int loops = Integer.parseInt(args[0]);
char[] eightChars = "01234567".toCharArray();
StringBuffer strB = new StringBuffer();
// simulate a large StringBuffer (eg an 0.5MB XML document) (UTF-8);
for (int i=0; i < (1024*1024/8); i++) {
strB.append(eightChars);
}
long start = 0;
long stop = 0;
String str = null;
System.out.println("Starting test");
start = System.currentTimeMillis();
for (int i=0; i < loops; i++) {
str = strB.toString();
}
stop = System.currentTimeMillis();
System.out.println("stoped test");
System.out.println("Duration of toString loop: " + (stop - start) + " milliseconds");
}
}
---------- END SOURCE ----------
###@###.### 2005-1-21 06:22:32 GMT
- duplicates
-
JDK-6395952 Concatenating String in jdk 5.0 will consume much more memory than in jdk 1.4.2
-
- Closed
-
-
JDK-6239985 StringBuilder/StringBuffer.toString() copies the character array
-
- Closed
-
- relates to
-
JDK-8013395 StringBuffer.toString performance regression impacting embedded benchmarks
-
- Resolved
-