Return-Path: Delivered-To: apmail-harmony-commits-archive@www.apache.org Received: (qmail 99188 invoked from network); 28 Apr 2009 06:13:36 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 28 Apr 2009 06:13:36 -0000 Received: (qmail 82015 invoked by uid 500); 28 Apr 2009 06:13:36 -0000 Delivered-To: apmail-harmony-commits-archive@harmony.apache.org Received: (qmail 81944 invoked by uid 500); 28 Apr 2009 06:13:36 -0000 Mailing-List: contact commits-help@harmony.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@harmony.apache.org Delivered-To: mailing list commits@harmony.apache.org Received: (qmail 81935 invoked by uid 99); 28 Apr 2009 06:13:36 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 28 Apr 2009 06:13:36 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 28 Apr 2009 06:13:34 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id A738723889DD; Tue, 28 Apr 2009 06:13:14 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r769259 - in /harmony/enhanced/classlib/trunk/modules/luni/src: main/java/java/lang/ test/api/common/org/apache/harmony/luni/tests/java/lang/ Date: Tue, 28 Apr 2009 06:13:13 -0000 To: commits@harmony.apache.org From: regisxu@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090428061314.A738723889DD@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: regisxu Date: Tue Apr 28 06:13:11 2009 New Revision: 769259 URL: http://svn.apache.org/viewvc?rev=769259&view=rev Log: Apply patch HARMONY-6045.v3.diff for HARMONY-6045: [classlib] [luni] Optimize java.lang.String.toUpperCase(), String.toLowerCase() and String sharing for more performance gains Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/AbstractStringBuilder.java harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/String.java harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/lang/StringBufferTest.java harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/lang/StringBuilderTest.java Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/AbstractStringBuilder.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/AbstractStringBuilder.java?rev=769259&r1=769258&r2=769259&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/AbstractStringBuilder.java (original) +++ harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/AbstractStringBuilder.java Tue Apr 28 06:13:11 2009 @@ -103,9 +103,6 @@ int newSize = count + 4; if (newSize > value.length) { enlargeBuffer(newSize); - } else if (shared) { - value = value.clone(); - shared = false; } value[count++] = 'n'; value[count++] = 'u'; @@ -117,9 +114,6 @@ int newSize = count + chars.length; if (newSize > value.length) { enlargeBuffer(newSize); - } else if (shared) { - value = value.clone(); - shared = false; } System.arraycopy(chars, 0, value, count, chars.length); count = newSize; @@ -134,9 +128,6 @@ int newSize = count + length; if (newSize > value.length) { enlargeBuffer(newSize); - } else if (shared) { - value = value.clone(); - shared = false; } System.arraycopy(chars, start, value, count, length); count = newSize; @@ -149,10 +140,6 @@ if (count == value.length) { enlargeBuffer(count + 1); } - if (shared) { - value = value.clone(); - shared = false; - } value[count++] = ch; } @@ -165,9 +152,6 @@ int newSize = count + adding; if (newSize > value.length) { enlargeBuffer(newSize); - } else if (shared) { - value = value.clone(); - shared = false; } string.getChars(0, adding, value, count); count = newSize; @@ -568,16 +552,16 @@ if (length < 0) { throw new StringIndexOutOfBoundsException(length); } - if (count < length) { - if (length > value.length) { - enlargeBuffer(length); + if (length > value.length) { + enlargeBuffer(length); + } else { + if (shared) { + char[] newData = new char[value.length]; + System.arraycopy(value, 0, newData, 0, count); + value = newData; + shared = false; } else { - if (shared) { - char[] newData = new char[value.length]; - System.arraycopy(value, 0, newData, 0, count); - value = newData; - shared = false; - } else { + if (count < length) { Arrays.fill(value, count, length, (char) 0); } } @@ -602,8 +586,8 @@ return ""; //$NON-NLS-1$ } - shared = true; - return new String(start, count - start, value); + // Remove String sharing for more performance + return new String(value, start, count - start); } throw new StringIndexOutOfBoundsException(start); } @@ -627,7 +611,7 @@ return ""; //$NON-NLS-1$ } - shared = true; + // Remove String sharing for more performance return new String(value, start, end - start); } throw new StringIndexOutOfBoundsException(); @@ -643,8 +627,10 @@ if (count == 0) { return ""; //$NON-NLS-1$ } - - if (count >= 256 && count <= (value.length >> 1)) { + // Optimize String sharing for more performance + int wasted = value.length - count; + if (wasted >= 256 + || (wasted >= INITIAL_CAPACITY && wasted >= (count >> 1))) { return new String(value, 0, count); } shared = true; Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/String.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/String.java?rev=769259&r1=769258&r2=769259&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/String.java (original) +++ harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/String.java Tue Apr 28 06:13:11 2009 @@ -591,6 +591,39 @@ throw new StringIndexOutOfBoundsException(); } + // Optimized for ASCII + private char compareValue(char ch) { + if (ch < 128) { + if ('A' <= ch && ch <= 'Z') { + return (char) (ch + ('a' - 'A')); + } + return ch; + } + return Character.toLowerCase(Character.toUpperCase(ch)); + } + + // Optimized for ASCII + private char toLowerCase(char ch) { + if (ch < 128) { + if ('A' <= ch && ch <= 'Z') { + return (char) (ch + ('a' - 'A')); + } + return ch; + } + return Character.toLowerCase(ch); + } + + // Optimized for ASCII + private char toUpperCase(char ch) { + if (ch < 128) { + if ('a' <= ch && ch <= 'z') { + return (char) (ch - ('a' - 'A')); + } + return ch; + } + return Character.toUpperCase(ch); + } + /** * Compares the specified String to this String using the Unicode values of * the characters. Answer 0 if the strings contain the same characters in @@ -643,8 +676,8 @@ if ((c1 = value[o1++]) == (c2 = target[o2++])) { continue; } - c1 = Character.toLowerCase(Character.toUpperCase(c1)); - c2 = Character.toLowerCase(Character.toUpperCase(c2)); + c1 = compareValue(c1); + c2 = compareValue(c2); if ((result = c1 - c2) != 0) { return result; } @@ -802,9 +835,9 @@ char[] target = string.value; while (o1 < end) { if ((c1 = value[o1++]) != (c2 = target[o2++]) - && Character.toUpperCase(c1) != Character.toUpperCase(c2) + && toUpperCase(c1) != toUpperCase(c2) // Required for unicode that we test both cases - && Character.toLowerCase(c1) != Character.toLowerCase(c2)) { + && toLowerCase(c1) != toLowerCase(c2)) { return false; } } @@ -1306,11 +1339,9 @@ char[] target = string.value; while (thisStart < end) { if ((c1 = value[thisStart++]) != (c2 = target[start++]) - && Character.toUpperCase(c1) != Character - .toUpperCase(c2) + && toUpperCase(c1) != toUpperCase(c2) // Required for unicode that we test both cases - && Character.toLowerCase(c1) != Character - .toLowerCase(c2)) { + && toLowerCase(c1) != toLowerCase(c2)) { return false; } } @@ -1500,7 +1531,7 @@ public String toLowerCase(Locale locale) { for (int o = offset, end = offset + count; o < end; o++) { char ch = value[o]; - if (ch != Character.toLowerCase(ch)) { + if (ch != toLowerCase(ch)) { char[] buffer = new char[count]; int i = o - offset; // Not worth checking for i == 0 case @@ -1508,12 +1539,12 @@ // Turkish if (!"tr".equals(locale.getLanguage())) { //$NON-NLS-1$ while (i < count) { - buffer[i++] = Character.toLowerCase(value[o++]); + buffer[i++] = toLowerCase(value[o++]); } } else { while (i < count) { - buffer[i++] = (ch = value[o++]) != 0x49 ? Character - .toLowerCase(ch) : (char) 0x131; + buffer[i++] = (ch = value[o++]) != 0x49 ? toLowerCase(ch) + : (char) 0x131; } } return new String(0, count, buffer); @@ -1626,8 +1657,8 @@ System.arraycopy(output, 0, newoutput, 0, output.length); output = newoutput; } - char upch = !turkish ? Character.toUpperCase(ch) - : (ch != 0x69 ? Character.toUpperCase(ch) + char upch = !turkish ? toUpperCase(ch) + : (ch != 0x69 ? toUpperCase(ch) : (char) 0x130); if (ch != upch) { if (output == null) { Modified: harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/lang/StringBufferTest.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/lang/StringBufferTest.java?rev=769259&r1=769258&r2=769259&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/lang/StringBufferTest.java (original) +++ harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/lang/StringBufferTest.java Tue Apr 28 06:13:11 2009 @@ -25,20 +25,89 @@ public class StringBufferTest extends TestCase { - /** - * @tests java.lang.StringBuffer#setLength(int) - */ - public void test_setLengthI() { - // Regression for HARMONY-90 - StringBuffer buffer = new StringBuffer("abcde"); - try { - buffer.setLength(-1); - fail("Assert 0: IndexOutOfBoundsException must be thrown"); - } catch (IndexOutOfBoundsException e) { - // expected - } - } - + /** + * @tests java.lang.StringBuffer#setLength(int) + */ + public void test_setLengthI() { + // Regression for HARMONY-90 + StringBuffer buffer = new StringBuffer("abcde"); + try { + buffer.setLength(-1); + fail("Assert 0: IndexOutOfBoundsException must be thrown"); + } catch (IndexOutOfBoundsException e) { + // expected + } + + assertEquals("abcde", buffer.toString()); + buffer.setLength(1); + buffer.append('f'); + assertEquals("af", buffer.toString()); + + buffer = new StringBuffer("abcde"); + assertEquals("cde", buffer.substring(2)); + buffer.setLength(3); + buffer.append('f'); + assertEquals("abcf", buffer.toString()); + + buffer = new StringBuffer("abcde"); + buffer.setLength(2); + try { + buffer.charAt(3); + fail("should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + buffer = new StringBuffer(); + buffer.append("abcdefg"); + buffer.setLength(2); + buffer.setLength(5); + for (int i = 2; i < 5; i++) { + assertEquals(0, buffer.charAt(i)); + } + + buffer = new StringBuffer(); + buffer.append("abcdefg"); + buffer.delete(2, 4); + buffer.setLength(7); + assertEquals('a', buffer.charAt(0)); + assertEquals('b', buffer.charAt(1)); + assertEquals('e', buffer.charAt(2)); + assertEquals('f', buffer.charAt(3)); + assertEquals('g', buffer.charAt(4)); + for (int i = 5; i < 7; i++) { + assertEquals(0, buffer.charAt(i)); + } + + buffer = new StringBuffer(); + buffer.append("abcdefg"); + buffer.replace(2, 5, "z"); + buffer.setLength(7); + for (int i = 5; i < 7; i++) { + assertEquals(0, buffer.charAt(i)); + } + } + + /** + * @tests java.lang.StringBuffer#toString() + */ + public void test_toString() throws Exception { + StringBuffer buffer = new StringBuffer(); + assertEquals("", buffer.toString()); + + buffer.append("abcde"); + assertEquals("abcde", buffer.toString()); + buffer.setLength(1000); + byte[] bytes = buffer.toString().getBytes("GB18030"); + for (int i = 5; i < bytes.length; i++) { + assertEquals(0, bytes[i]); + } + + buffer.setLength(5); + buffer.append("fghij"); + assertEquals("abcdefghij", buffer.toString()); + } + /** * @tests StringBuffer.StringBuffer(CharSequence); */ Modified: harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/lang/StringBuilderTest.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/lang/StringBuilderTest.java?rev=769259&r1=769258&r2=769259&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/lang/StringBuilderTest.java (original) +++ harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/lang/StringBuilderTest.java Tue Apr 28 06:13:11 2009 @@ -1725,6 +1725,55 @@ } catch (IndexOutOfBoundsException e) { // Expected } + + sb = new StringBuilder("abcde"); + assertEquals("abcde", sb.toString()); + sb.setLength(1); + sb.append('g'); + assertEquals("ag", sb.toString()); + + sb = new StringBuilder("abcde"); + sb.setLength(3); + sb.append('g'); + assertEquals("abcg", sb.toString()); + + sb = new StringBuilder("abcde"); + sb.setLength(2); + try { + sb.charAt(3); + fail("should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + sb = new StringBuilder(); + sb.append("abcdefg"); + sb.setLength(2); + sb.setLength(5); + for (int i = 2; i < 5; i++) { + assertEquals(0, sb.charAt(i)); + } + + sb = new StringBuilder(); + sb.append("abcdefg"); + sb.delete(2, 4); + sb.setLength(7); + assertEquals('a', sb.charAt(0)); + assertEquals('b', sb.charAt(1)); + assertEquals('e', sb.charAt(2)); + assertEquals('f', sb.charAt(3)); + assertEquals('g', sb.charAt(4)); + for (int i = 5; i < 7; i++) { + assertEquals(0, sb.charAt(i)); + } + + sb = new StringBuilder(); + sb.append("abcdefg"); + sb.replace(2, 5, "z"); + sb.setLength(7); + for (int i = 5; i < 7; i++) { + assertEquals(0, sb.charAt(i)); + } } /** @@ -1843,14 +1892,27 @@ } } - /** - * @tests java.lang.StringBuilder.toString()' - */ - public void test_toString() { - final String fixture = "0123456789"; - StringBuilder sb = new StringBuilder(fixture); - assertEquals(fixture, sb.toString()); - } + /** + * @tests java.lang.StringBuilder.toString()' + */ + public void test_toString() throws Exception { + final String fixture = "0123456789"; + StringBuilder sb = new StringBuilder(fixture); + assertEquals(fixture, sb.toString()); + + sb.setLength(0); + sb.append("abcde"); + assertEquals("abcde", sb.toString()); + sb.setLength(1000); + byte[] bytes = sb.toString().getBytes("GB18030"); + for (int i = 5; i < bytes.length; i++) { + assertEquals(0, bytes[i]); + } + + sb.setLength(5); + sb.append("fghij"); + assertEquals("abcdefghij", sb.toString()); + } /** * @tests java.lang.StringBuilder.trimToSize()'