Dear Core-Lib Developers,

I like to contribute an explicit implementation of InputStreamReader.readAllAsString() for performance reasons.

I benchmarked InputStreamReader.readAllAsString() vs simplistic custom code, and the result is pretty clear: Even most trivial custom code clearly outperforms the original code by more than 30%!

Benchmark         Mode  Cnt      Score     Error  Units
Demo.jdk         thrpt   25  10931.806 ± 535.177  ops/s
Demo.customCode  thrpt   25  14775.102 ± 343.829  ops/s

@Benchmark
public String jdk(MyState ms) throws IOException {
  return new InputStreamReader(ms.in, UTF_8).readAllAsString();
}

@Benchmark
public String trivialCustomCode(MyState ms) throws IOException {
  return new String(ms.in.readAllBytes(), UTF_8);
}

IMHO gaining 30%+ justifies the provision of a custom implementation like the following one...

public String readAllAsString() throws IOException {
  return sd.readAllAsString();
}

and in turn let sd.readAllAsString() return e. g. new String(in.readAllBytes(), cs)

...to override Reader's default implementation which currently performs (possibly lots of) several in-builder buffer copies:

public String readAllAsString() throws IOException {
  StringBuilder result = new StringBuilder();
  char[] cbuf = new char[TRANSFER_BUFFER_SIZE];
  int nread;
  while ((nread = read(cbuf, 0, cbuf.length)) != -1) {
      result.append(cbuf, 0, nread);
  }
  return result.toString();
}

This minimal change should provide approx. the benchmarked 30% performance gain, should never be slower, and should not need more memory than the original implementation.

If the core-libs team is fine with me doing so, I would like to file a JBS and a PR. Comments very welcome!

-Markus

Reply via email to