Skip to content

Commit 4a3ee4d

Browse files
author
Rob Stryker
committed
Improve performance in CharOperation
Signed-off-by: Rob Stryker <stryker@redhat.com>
1 parent c002247 commit 4a3ee4d

File tree

2 files changed

+29
-52
lines changed

2 files changed

+29
-52
lines changed

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/CharOperation.java

Lines changed: 8 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3734,59 +3734,15 @@ public static final void replace(char[] array, char[] toBeReplaced, char replace
37343734
* @throws NullPointerException if the given array is null
37353735
*/
37363736
public static final char[] replace(
3737-
char[] array,
3738-
char[] toBeReplaced,
3739-
char[] replacementChars) {
3740-
3741-
int max = array.length;
3742-
int replacedLength = toBeReplaced.length;
3743-
int replacementLength = replacementChars.length;
3744-
3745-
int[] starts = new int[5];
3746-
int occurrenceCount = 0;
3747-
3748-
if (!equals(toBeReplaced, replacementChars)) {
3749-
3750-
next : for (int i = 0; i < max;) {
3751-
int index = indexOf(toBeReplaced, array, true, i);
3752-
if (index == -1) {
3753-
i++;
3754-
continue next;
3755-
}
3756-
if (occurrenceCount == starts.length) {
3757-
System.arraycopy(
3758-
starts,
3759-
0,
3760-
starts = new int[occurrenceCount * 2],
3761-
0,
3762-
occurrenceCount);
3763-
}
3764-
starts[occurrenceCount++] = index;
3765-
i = index + replacedLength;
3737+
char[] array,
3738+
char[] toBeReplaced,
3739+
char[] replacementChars) {
3740+
String s1 = new String(array);
3741+
String myRet = s1.replace(new String(toBeReplaced), new String(replacementChars));
3742+
if( myRet.equals(s1)) {
3743+
return array;
37663744
}
3767-
}
3768-
if (occurrenceCount == 0)
3769-
return array;
3770-
char[] result =
3771-
new char[max
3772-
+ occurrenceCount * (replacementLength - replacedLength)];
3773-
int inStart = 0, outStart = 0;
3774-
for (int i = 0; i < occurrenceCount; i++) {
3775-
int offset = starts[i] - inStart;
3776-
System.arraycopy(array, inStart, result, outStart, offset);
3777-
inStart += offset;
3778-
outStart += offset;
3779-
System.arraycopy(
3780-
replacementChars,
3781-
0,
3782-
result,
3783-
outStart,
3784-
replacementLength);
3785-
inStart += replacedLength;
3786-
outStart += replacementLength;
3787-
}
3788-
System.arraycopy(array, inStart, result, outStart, max - inStart);
3789-
return result;
3745+
return myRet.toCharArray();
37903746
}
37913747

37923748
/**

org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CharOperationTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,4 +170,25 @@ public void test012() {
170170
4,
171171
true));
172172
}
173+
174+
public void testReplacePerformance001() {
175+
// This is the test that takes an excessively long time
176+
// The improvement here is drastic, 99% reduction in time
177+
testReplaceImpl("This is one line with no matches\n", 9, 0.01);
178+
}
179+
180+
private void testReplaceImpl(String oneLine, int power, double multiplier) {
181+
String total = oneLine;
182+
for( int i = 0; i < power; i++ ) {
183+
total = total + total; // Double the length
184+
}
185+
total = oneLine + total;
186+
187+
// Now replace
188+
long start = System.currentTimeMillis();
189+
char[] found = CharOperation.replace(total.toCharArray(), new char[]{'/'}, new char[] {'z'});
190+
long end = System.currentTimeMillis();
191+
long spent = end - start;
192+
assertTrue(spent < 10);
193+
}
173194
}

0 commit comments

Comments
 (0)