diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/CharOperation.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/CharOperation.java index 5933dbd1958..d5cb60c0a4d 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/CharOperation.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/CharOperation.java @@ -3734,59 +3734,15 @@ public static final void replace(char[] array, char[] toBeReplaced, char replace * @throws NullPointerException if the given array is null */ public static final char[] replace( - char[] array, - char[] toBeReplaced, - char[] replacementChars) { - - int max = array.length; - int replacedLength = toBeReplaced.length; - int replacementLength = replacementChars.length; - - int[] starts = new int[5]; - int occurrenceCount = 0; - - if (!equals(toBeReplaced, replacementChars)) { - - next : for (int i = 0; i < max;) { - int index = indexOf(toBeReplaced, array, true, i); - if (index == -1) { - i++; - continue next; - } - if (occurrenceCount == starts.length) { - System.arraycopy( - starts, - 0, - starts = new int[occurrenceCount * 2], - 0, - occurrenceCount); - } - starts[occurrenceCount++] = index; - i = index + replacedLength; + char[] array, + char[] toBeReplaced, + char[] replacementChars) { + String s1 = new String(array); + String myRet = s1.replace(new String(toBeReplaced), new String(replacementChars)); + if( myRet.equals(s1)) { + return array; } - } - if (occurrenceCount == 0) - return array; - char[] result = - new char[max - + occurrenceCount * (replacementLength - replacedLength)]; - int inStart = 0, outStart = 0; - for (int i = 0; i < occurrenceCount; i++) { - int offset = starts[i] - inStart; - System.arraycopy(array, inStart, result, outStart, offset); - inStart += offset; - outStart += offset; - System.arraycopy( - replacementChars, - 0, - result, - outStart, - replacementLength); - inStart += replacedLength; - outStart += replacementLength; - } - System.arraycopy(array, inStart, result, outStart, max - inStart); - return result; + return myRet.toCharArray(); } /** diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CharOperationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CharOperationTest.java index a2164eba878..4d34bb896d1 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CharOperationTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CharOperationTest.java @@ -170,4 +170,25 @@ public void test012() { 4, true)); } + +public void testReplacePerformance001() { + // This is the test that takes an excessively long time + // The improvement here is drastic, 99% reduction in time + testReplaceImpl("This is one line with no matches\n", 9, 0.01); +} + +private void testReplaceImpl(String oneLine, int power, double multiplier) { + String total = oneLine; + for( int i = 0; i < power; i++ ) { + total = total + total; // Double the length + } + total = oneLine + total; + + // Now replace + long start = System.currentTimeMillis(); + char[] found = CharOperation.replace(total.toCharArray(), new char[]{'/'}, new char[] {'z'}); + long end = System.currentTimeMillis(); + long spent = end - start; + assertTrue(spent < 10); +} }