Skip to content

Conversation

stsypanov
Copy link
Contributor

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

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Apr 6, 2020
@sbrannen sbrannen requested a review from jhoeller April 6, 2020 17:25
@sbrannen sbrannen added in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement labels Apr 6, 2020
@jhoeller jhoeller self-assigned this Apr 7, 2020
@jhoeller jhoeller removed the status: waiting-for-triage An issue we've not yet triaged or decided on label Apr 7, 2020
@jhoeller jhoeller added this to the 5.2.6 milestone Apr 7, 2020
@jhoeller jhoeller merged commit e1951a0 into spring-projects:master Apr 9, 2020
@stsypanov stsypanov deleted the su branch April 12, 2020 07:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants