StringUtils.deleteAny() can be improved in a trivial way to reduce bounds check and possible reallocations in StringBuilder by using char[]. This simple change demonstrates significant improvement.
Benchmark:
@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Fork(jvmArgsAppend = {"-Xms2g", "-Xmx2g", "-XX:+UseParallelGC"})
public class DeleteAnyBenchmark {
@Benchmark
public String original() {
return deleteAny("key1=value1 ", "\"");
}
@Benchmark
public String patched() {
return deleteAnyPatched("key1=value1 ", "\"");
}
private static String deleteAny(String inString, String charsToDelete) {
StringBuilder sb = new StringBuilder(inString.length());
for (int i = 0; i < inString.length(); i++) {
char c = inString.charAt(i);
if (charsToDelete.indexOf(c) == -1) {
sb.append(c);
}
}
return sb.toString();
}
private static String deleteAnyPatched(String inString, String charsToDelete) {
int lastCharIndex = 0;
char[] result = new char[inString.length()];
for (int i = 0; i < inString.length(); i++) {
char c = inString.charAt(i);
if (charsToDelete.indexOf(c) == -1) {
result[lastCharIndex++] = c;
}
}
return new String(result, 0, lastCharIndex);
}
}
and its results for Java 8
Benchmark Mode Cnt Score Error Units
DeleteAnyBenchmark.original avgt 50 90.203 ± 4.317 ns/op
DeleteAnyBenchmark.original:·gc.alloc.rate avgt 50 738.784 ± 31.462 MB/sec
DeleteAnyBenchmark.original:·gc.alloc.rate.norm avgt 50 104.000 ± 0.001 B/op
DeleteAnyBenchmark.original:·gc.churn.PS_Eden_Space avgt 50 750.517 ± 107.126 MB/sec
DeleteAnyBenchmark.original:·gc.churn.PS_Eden_Space.norm avgt 50 105.389 ± 14.303 B/op
DeleteAnyBenchmark.original:·gc.churn.PS_Survivor_Space avgt 50 0.030 ± 0.015 MB/sec
DeleteAnyBenchmark.original:·gc.churn.PS_Survivor_Space.norm avgt 50 0.004 ± 0.002 B/op
DeleteAnyBenchmark.original:·gc.count avgt 50 83.000 counts
DeleteAnyBenchmark.original:·gc.time avgt 50 84.000 ms
DeleteAnyBenchmark.patched avgt 50 25.391 ± 1.118 ns/op
DeleteAnyBenchmark.patched:·gc.alloc.rate avgt 50 2622.055 ± 107.408 MB/sec
DeleteAnyBenchmark.patched:·gc.alloc.rate.norm avgt 50 104.000 ± 0.001 B/op
DeleteAnyBenchmark.patched:·gc.churn.PS_Eden_Space avgt 50 2606.384 ± 126.905 MB/sec
DeleteAnyBenchmark.patched:·gc.churn.PS_Eden_Space.norm avgt 50 103.466 ± 3.549 B/op
DeleteAnyBenchmark.patched:·gc.churn.PS_Survivor_Space avgt 50 0.066 ± 0.015 MB/sec
DeleteAnyBenchmark.patched:·gc.churn.PS_Survivor_Space.norm avgt 50 0.003 ± 0.001 B/op
DeleteAnyBenchmark.patched:·gc.count avgt 50 287.000 counts
DeleteAnyBenchmark.patched:·gc.time avgt 50 260.000 ms