Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8076758

new StringBuilder().append(String).toString() should be recognized by OptimizeStringConcat

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Fixed
    • Icon: P4 P4
    • 9
    • 9
    • hotspot
    • None
    • b82

        There is a corner case in String optimizations that is missing. It's a questionable programming practice, since the code sequence should just be replaced by "new String(s)", or even "s" assuming the new identity is not required. However, it might be trivial to support in OptimizeStringConcat?

        @State(Scope.Benchmark)
        @BenchmarkMode(Mode.AverageTime)
        @OutputTimeUnit(TimeUnit.NANOSECONDS)
        @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
        @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
        @Fork(3)
        public class ConcatSimpleBench {

            @Param({"1", "64", "4096"})
            int size;

            private String s;

            @Setup
            public void setup() {
                s = "";
                for (int c = 0; c < size; c++) {
                    s += "a";
                }
            }

            @Benchmark
            @CompilerControl(CompilerControl.Mode.DONT_INLINE)
            public String base() {
                return new String(s);
            }

            @Benchmark
            @CompilerControl(CompilerControl.Mode.DONT_INLINE)
            public String sb() {
                return new StringBuilder().append(s).toString();
            }
        }

        Yields:

        Benchmark (size) Mode Cnt Score Error Units
        ConcatSimpleBench.base 1 avgt 15 4.971 ± 0.992 ns/op
        ConcatSimpleBench.base 64 avgt 15 4.972 ± 1.044 ns/op
        ConcatSimpleBench.base 4096 avgt 15 5.249 ± 1.045 ns/op
        ConcatSimpleBench.sb 1 avgt 15 11.267 ± 2.628 ns/op
        ConcatSimpleBench.sb 64 avgt 15 16.219 ± 0.296 ns/op
        ConcatSimpleBench.sb 4096 avgt 15 814.078 ± 12.745 ns/op

        "base" tests experiences constant-time performance (the char[] array is just shared). "sb" test experiences close to O(n), since it copies the backing char[] storage.

              shade Aleksey Shipilev
              shade Aleksey Shipilev
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved: