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;

Reply via email to