Patch: StringBuffer optimization
Anthony Green
green@cygnus.com
Sat Apr 8 21:46:00 GMT 2000
Profiling the Embedded CaffeineMark is very educational. It points
out an obvious opportunity to eliminate many costly calls to
_Jv_MonitorEnter/_Jv_MonitorExit.
I've also replaced a call to java.lang.Math.max.
2000-04-08 Anthony Green <green@cygnus.com>
* java/lang/StringBuffer.java (ensureCapacity): Don't call Math::max.
(ensureCapacity_unsynchronized): New private method.
(append): Use ensureCapacity_unsynchronized.
Index: libjava/java/lang/StringBuffer.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/lang/StringBuffer.java,v
retrieving revision 1.3
diff -c -r1.3 StringBuffer.java
*** StringBuffer.java 2000/01/17 00:00:43 1.3
--- StringBuffer.java 2000/04/09 04:39:07
***************
*** 28,34 ****
public synchronized StringBuffer append (char ch)
{
! ensureCapacity (count + 1);
value[count++] = ch;
return this;
}
--- 28,34 ----
public synchronized StringBuffer append (char ch)
{
! ensureCapacity_unsynchronized (count + 1);
value[count++] = ch;
return this;
}
***************
*** 63,69 ****
if (str == null)
str = "null";
int len = str.length();
! ensureCapacity (count + len);
str.getChars(0, len, value, count);
count += len;
return this;
--- 63,69 ----
if (str == null)
str = "null";
int len = str.length();
! ensureCapacity_unsynchronized (count + len);
str.getChars(0, len, value, count);
count += len;
return this;
***************
*** 76,82 ****
public synchronized StringBuffer append (char[] data, int offset, int count)
{
! ensureCapacity (this.count + count);
System.arraycopy(data, offset, value, this.count, count);
this.count += count;
return this;
--- 76,82 ----
public synchronized StringBuffer append (char[] data, int offset, int count)
{
! ensureCapacity_unsynchronized (this.count + count);
System.arraycopy(data, offset, value, this.count, count);
this.count += count;
return this;
***************
*** 104,110 ****
int max = (minimumCapacity > value.length
? value.length*2+2
: value.length);
! minimumCapacity = Math.max(minimumCapacity, max);
char[] nb = new char[minimumCapacity];
System.arraycopy(value, 0, nb, 0, count);
value = nb;
--- 104,110 ----
int max = (minimumCapacity > value.length
? value.length*2+2
: value.length);
! minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
char[] nb = new char[minimumCapacity];
System.arraycopy(value, 0, nb, 0, count);
value = nb;
***************
*** 112,117 ****
--- 112,137 ----
}
}
+ // ensureCapacity is used by several synchronized methods in StringBuffer.
+ // There's no need to synchronize again.
+ private void ensureCapacity_unsynchronized (int minimumCapacity)
+ {
+ if (shared || minimumCapacity > value.length)
+ {
+ // We don't want to make a larger vector when `shared' is
+ // set. If we do, then setLength becomes very inefficient
+ // when repeatedly reusing a StringBuffer in a loop.
+ int max = (minimumCapacity > value.length
+ ? value.length*2+2
+ : value.length);
+ minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
+ char[] nb = new char[minimumCapacity];
+ System.arraycopy(value, 0, nb, 0, count);
+ value = nb;
+ shared = false;
+ }
+ }
+
public synchronized void getChars (int srcOffset, int srcEnd,
char[] dst, int dstOffset)
{
***************
*** 132,138 ****
{
if (offset < 0 || offset > count)
throw new StringIndexOutOfBoundsException (offset);
! ensureCapacity (count+1);
System.arraycopy(value, offset, value, offset+1, count-offset);
value[offset] = ch;
count++;
--- 152,158 ----
{
if (offset < 0 || offset > count)
throw new StringIndexOutOfBoundsException (offset);
! ensureCapacity_unsynchronized (count+1);
System.arraycopy(value, offset, value, offset+1, count-offset);
value[offset] = ch;
count++;
***************
*** 172,178 ****
if (str == null)
str = "null";
int len = str.length();
! ensureCapacity(count+len);
System.arraycopy(value, offset, value, offset+len, count-offset);
str.getChars(0, len, value, offset);
count += len;
--- 192,198 ----
if (str == null)
str = "null";
int len = str.length();
! ensureCapacity_unsynchronized (count+len);
System.arraycopy(value, offset, value, offset+len, count-offset);
str.getChars(0, len, value, offset);
count += len;
***************
*** 184,190 ****
if (offset < 0 || offset > count)
throw new StringIndexOutOfBoundsException (offset);
int len = data.length;
! ensureCapacity (count+len);
System.arraycopy(value, offset, value, offset+len, count-offset);
System.arraycopy(data, 0, value, offset, len);
count += len;
--- 204,210 ----
if (offset < 0 || offset > count)
throw new StringIndexOutOfBoundsException (offset);
int len = data.length;
! ensureCapacity_unsynchronized (count+len);
System.arraycopy(value, offset, value, offset+len, count-offset);
System.arraycopy(data, 0, value, offset, len);
count += len;
***************
*** 212,218 ****
if (index < 0 || index >= count)
throw new StringIndexOutOfBoundsException (index);
// Call ensureCapacity to enforce copy-on-write.
! ensureCapacity (count);
value[index] = ch;
}
--- 232,238 ----
if (index < 0 || index >= count)
throw new StringIndexOutOfBoundsException (index);
// Call ensureCapacity to enforce copy-on-write.
! ensureCapacity_unsynchronized (count);
value[index] = ch;
}
***************
*** 221,227 ****
if (newLength < 0)
throw new StringIndexOutOfBoundsException (newLength);
! ensureCapacity (newLength);
for (int i = count; i < newLength; ++i)
value[i] = '\0';
count = newLength;
--- 241,247 ----
if (newLength < 0)
throw new StringIndexOutOfBoundsException (newLength);
! ensureCapacity_unsynchronized (newLength);
for (int i = count; i < newLength; ++i)
value[i] = '\0';
count = newLength;
More information about the Java-patches
mailing list