8011135: (bf) CharBuffer.put(String) is slow because of String.charAt() call for each char

Claes Redestad claes.redestad at oracle.com
Thu Feb 21 10:31:04 UTC 2019


Hi Brian,

patch looks good to me, but the new implementation will throw
BufferOverflowException before writing anything to the buffer, whereas
the old one would fill up the CharBuffer. I'm not sure this change in
behavior is acceptable, and it should be straightforward to fix.

Benchmark looks OK. I'd parameterize it so you test with a mix from
tiny to really long Strings, along with variants that contain higher
unicode codepoints for bonus points. Feel free to contribute it under
test/micro.

Thanks!

/Claes

On 2019-02-20 23:07, Brian Burkhalter wrote:
> https://bugs.openjdk.java.net/browse/JDK-8011135
> 
> With the proposed change [1] applied, the performance of 
> CharBuffer.put(String) was measured [2] to be 5-6X faster than without 
> the change [3].
> 
> Thanks,
> 
> Brian
> 
> [1] diff
> 
> --- a/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template
> +++ b/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template
> @@ -270,6 +270,22 @@
>   #end[rw]
>       }
> 
> 
> +#if[char]
> +
> +    public $Type$Buffer put(String src, int start, int end) {
> +        int length = end - start;
> +        checkBounds(start, length, src.length());
> +        if (isReadOnly())
> +            throw new ReadOnlyBufferException();
> +        if (length > remaining())
> +            throw new BufferOverflowException();
> +        src.getChars(start, end, hb, ix(position()));
> +        position(position() + length);
> +        return this;
> +    }
> +
> +#end[char]
> +
>       public $Type$Buffer compact() {
> 
> 
> [2] benchmark
> 
> public class PutStringBench {
> 
>      private static final String STR = new String
>          (" 
> abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ");
> 
>      private static final CharBuffer BUF = CharBuffer.allocate(1024);
> 
>      @Benchmark
>      public CharBuffer putString() {
>          BUF.rewind();
>          return BUF.put(STR);
>      }
> 
> }
> 
> 
> [3] results
> [a] before
> 
> Result "com.oracle.PutStringBench.putString":
>    18764158.739 ±(99.9%) 250376.712 ops/s [Average]
>    (min, avg, max) = (18614233.510, 18764158.739, 19122478.453), stdev = 
> 165608.693
>    CI (99.9%): [18513782.027, 19014535.452] (assumes normal distribution)
> 
> Result "com.oracle.PutStringBench.putString":
>    15920473.709 ±(99.9%) 1212446.652 ops/s [Average]
>    (min, avg, max) = (14842084.221, 15920473.709, 17371424.249), stdev = 
> 801958.390
>    CI (99.9%): [14708027.056, 17132920.361] (assumes normal distribution)
> 
> Benchmark                  Mode  Cnt         Score        Error  Units
> PutStringBench.putString  thrpt    5  18571082.538 ± 693010.965  ops/s
> 
> [b] after
> 
> Result "com.oracle.PutStringBench.putString":
>    108696688.710 ±(99.9%) 3774080.561 ops/s [Average]
>    (min, avg, max) = (101907400.750, 108696688.710, 110524934.117), 
> stdev = 2496320.615
>    CI (99.9%): [104922608.149, 112470769.272] (assumes normal distribution)
> 
> Result "com.oracle.PutStringBench.putString":
>    103110531.621 ±(99.9%) 5281599.715 ops/s [Average]
>    (min, avg, max) = (96691960.810, 103110531.621, 106781180.294), stdev 
> = 3493451.195
>    CI (99.9%): [97828931.906, 108392131.336] (assumes normal distribution)
> 
> Benchmark                  Mode  Cnt          Score         Error  Units
> PutStringBench.putString  thrpt    5  106026596.397 ± 1375553.439  ops/s
> 


More information about the nio-dev mailing list