On Wed, 13 Jan 2021 13:48:40 GMT, Claes Redestad <redes...@openjdk.org> wrote:
>> Instead of allocating a copy of underlying array via >> `CharArrayWriter.toCharArray()` and passing it to constructor of String >> String str = new String(charArrayWriter.toCharArray()); >> we could call `toString()` method >> String str = charArrayWriter.toString(); >> decoding existing char[] without making a copy. This slightly speeds up the >> method reducing at the same time memory consumption for decoding URLs with >> non-latin symbols: >> @State(Scope.Thread) >> @BenchmarkMode(Mode.AverageTime) >> @OutputTimeUnit(TimeUnit.NANOSECONDS) >> @Fork(jvmArgsAppend = {"-Xms2g", "-Xmx2g"}) >> public class UrlEncoderBenchmark { >> private static final Charset charset = Charset.defaultCharset(); >> private static final String utf8Url = >> "https://ru.wikipedia.org/wiki/Организация_Объединённых_Наций"; // UN >> >> @Benchmark >> public String encodeUtf8() { >> return URLEncoder.encode(utf8Url, charset); >> } >> } >> The benchmark on my maching give the following output: >> before >> Benchmark Mode Cnt >> Score Error Units >> UrlEncoderBenchmark.encodeUtf8 avgt 100 >> 1166.378 ± 8.411 ns/op >> UrlEncoderBenchmark.encodeUtf8:·gc.alloc.rate avgt 100 >> 932.944 ± 6.393 MB/sec >> UrlEncoderBenchmark.encodeUtf8:·gc.alloc.rate.norm avgt 100 >> 1712.193 ± 0.005 B/op >> UrlEncoderBenchmark.encodeUtf8:·gc.churn.G1_Eden_Space avgt 100 >> 929.221 ± 24.268 MB/sec >> UrlEncoderBenchmark.encodeUtf8:·gc.churn.G1_Eden_Space.norm avgt 100 >> 1705.444 ± 43.235 B/op >> UrlEncoderBenchmark.encodeUtf8:·gc.churn.G1_Survivor_Space avgt 100 >> 0.006 ± 0.001 MB/sec >> UrlEncoderBenchmark.encodeUtf8:·gc.churn.G1_Survivor_Space.norm avgt 100 >> 0.011 ± 0.002 B/op >> UrlEncoderBenchmark.encodeUtf8:·gc.count avgt 100 >> 652.000 counts >> UrlEncoderBenchmark.encodeUtf8:·gc.time avgt 100 >> 334.000 ms >> >> after >> Benchmark Mode Cnt >> Score Error Units >> UrlEncoderBenchmark.encodeUtf8 avgt 100 >> 1058.851 ± 6.006 ns/op >> UrlEncoderBenchmark.encodeUtf8:·gc.alloc.rate avgt 100 >> 931.489 ± 5.182 MB/sec >> UrlEncoderBenchmark.encodeUtf8:·gc.alloc.rate.norm avgt 100 >> 1552.176 ± 0.005 B/op >> UrlEncoderBenchmark.encodeUtf8:·gc.churn.G1_Eden_Space avgt 100 >> 933.491 ± 24.164 MB/sec >> UrlEncoderBenchmark.encodeUtf8:·gc.churn.G1_Eden_Space.norm avgt 100 >> 1555.488 ± 39.204 B/op >> UrlEncoderBenchmark.encodeUtf8:·gc.churn.G1_Survivor_Space avgt 100 >> 0.006 ± 0.001 MB/sec >> UrlEncoderBenchmark.encodeUtf8:·gc.churn.G1_Survivor_Space.norm avgt 100 >> 0.010 ± 0.002 B/op >> UrlEncoderBenchmark.encodeUtf8:·gc.count avgt 100 >> 655.000 counts >> UrlEncoderBenchmark.encodeUtf8:·gc.time avgt 100 >> 333.000 ms > > Looks good. > > I wonder... `CharArrayWriter` is an old and synchronized data structure, and > since the instance used here isn't shared that synchronization seem useless. > And since you're now bypassing the `char[]` and going straight for a `String` > you might get better performance with a `StringBuilder` here? (`setLength(0)` > instead of `reset()`...) @cl4es hi, let me try `StringBuilder` ------------- PR: https://git.openjdk.java.net/jdk/pull/1598