Hello all,
here's a revised patch that removes the use of clone in preference to
just array copying the "live" portion of the String. Here are the DaCapo
xalan figures:
run 1: 97972ms
run 2: 97837ms
run 3: 95290ms
which represents anything from a 0.04% slow down to a 2.8% speed up.
There will also be a space saving as we're not cloning whole arrays any
more. Please let me know if you think this patch is suitable for inclusion.
Thanks,
Ian
--- java/lang/String.java 2008-01-23 09:01:02.000000000 +0000
+++ java/lang/String.java 2008-02-05 10:07:56.000000000 +0000
@@ -1303,13 +1303,13 @@
break;
if (i < 0)
return this;
- char[] newStr = (char[]) value.clone();
- newStr[x] = newChar;
+ char[] newStr = toCharArray();
+ newStr[x-offset] = newChar;
while (--i >= 0)
if (value[++x] == oldChar)
- newStr[x] = newChar;
+ newStr[x-offset] = newChar;
// Package constructor avoids an array copy.
- return new String(newStr, offset, count, true);
+ return new String(newStr, 0, count, true);
}
/**
@@ -1450,23 +1450,25 @@
// Now we perform the conversion. Fortunately, there are no multi-character
// lowercase expansions in Unicode 3.0.0.
- char[] newStr = (char[]) value.clone();
+ char[] newStr = new char[count];
+ VMSystem.arraycopy(value, offset, newStr, 0, count-(x-offset));
do
{
char ch = value[x];
// Hardcoded special case.
if (ch != '\u0049')
{
- newStr[x++] = Character.toLowerCase(ch);
+ newStr[x-offset] = Character.toLowerCase(ch);
}
else
{
- newStr[x++] = '\u0131';
+ newStr[x-offset] = '\u0131';
}
+ x++;
}
while (--i >= 0);
// Package constructor avoids an array copy.
- return new String(newStr, offset, count, true);
+ return new String(newStr, 0, count, true);
}
/**
@@ -1504,16 +1506,18 @@
// Now we perform the conversion. Fortunately, there are no
// multi-character lowercase expansions in Unicode 3.0.0.
- char[] newStr = (char[]) value.clone();
+ char[] newStr = new char[count];
+ VMSystem.arraycopy(value, offset, newStr, 0, count-(x-offset));
do
{
char ch = value[x];
// Hardcoded special case.
- newStr[x++] = Character.toLowerCase(ch);
+ newStr[x-offset] = Character.toLowerCase(ch);
+ x++;
}
while (--i >= 0);
// Package constructor avoids an array copy.
- return new String(newStr, offset, count, true);
+ return new String(newStr, 0, count, true);
}
}
@@ -1557,22 +1561,24 @@
i = count;
if (expand == 0)
{
- char[] newStr = (char[]) value.clone();
+ char[] newStr = new char[count];
+ VMSystem.arraycopy(value, offset, newStr, 0, count-(x-offset));
while (--i >= 0)
{
char ch = value[x];
// Hardcoded special case.
if (ch != '\u0069')
{
- newStr[x++] = Character.toUpperCase(ch);
+ newStr[x-offset] = Character.toUpperCase(ch);
}
else
{
- newStr[x++] = '\u0130';
+ newStr[x-offset] = '\u0130';
}
+ x++;
}
// Package constructor avoids an array copy.
- return new String(newStr, offset, count, true);
+ return new String(newStr, 0, count, true);
}
// Expansion is necessary.
@@ -1642,14 +1648,16 @@
i = count;
if (expand == 0)
{
- char[] newStr = (char[]) value.clone();
+ char[] newStr = new char[count];
+ VMSystem.arraycopy(value, offset, newStr, 0, count-(x-offset));
while (--i >= 0)
{
char ch = value[x];
- newStr[x++] = Character.toUpperCase(ch);
+ newStr[x-offset] = Character.toUpperCase(ch);
+ x++;
}
// Package constructor avoids an array copy.
- return new String(newStr, offset, count, true);
+ return new String(newStr, 0, count, true);
}
// Expansion is necessary.
@@ -1730,9 +1738,6 @@
*/
public char[] toCharArray()
{
- if (count == value.length)
- return (char[]) value.clone();
-
char[] copy = new char[count];
VMSystem.arraycopy(value, offset, copy, 0, count);
return copy;