Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve performance of StringUtils.deleteAny() #24870

Merged
merged 1 commit into from
Apr 9, 2020

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.

None yet

4 participants