I/O had always been much slower than CPU and memory access, and thanks to 
physical constraints, always will be.
While CPUs can get shrinked more and more, and can hold more and more memory 
cache on or nearby a CPU core, the distance between CPU core and I/O device 
cannot get reduced much: It will stay "far" away.
Due to this simple logic (and other factors), the spread between performance of 
CPU and memory access on one hand, and performance of I/O on the other hand, 
increases with every new CPU generation.
As a consequence, internal adjustment factors of the JDK need to get revised 
from time to time to ensure optimum performance and each hardware generation.

One such factor is the size of the temporary transfer buffer used internally by 
`InputStream::transferTo`.
Since its introduction with JDK 9 many years (hence hardware generations) have 
passed, so it's time to check the appropriateness of that buffer's size.

Using JMH on a typical, modern cloud platform, it was proven that the current 
8K buffer is (much) too small on modern hardware:
The small buffer clearly stands in the way of faster transfers.
The ops/s of a simple `FileInputStream.transferTo(ByteArrayOutputStream)` 
operation on JDK 21 could be doubled (!) by only doubling the buffer size from 
8K to 16K, which seems to be a considerable and cheap deal.
Doubling the buffer even more shows only marginal improvements of approx. 1% to 
3% per duplication of size, which does not justify additional memory 
consumption.


TransferToPerformance.transferTo 8192 1048576 thrpt 25 1349.929 ± 47.057 ops/s
TransferToPerformance.transferTo 16384 1048576 thrpt 25 2633.560 ± 93.337 ops/s
TransferToPerformance.transferTo 32768 1048576 thrpt 25 2721.025 ± 89.555 ops/s
TransferToPerformance.transferTo 65536 1048576 thrpt 25 2855.949 ± 96.623 ops/s
TransferToPerformance.transferTo 131072 1048576 thrpt 25 2903.062 ± 40.798 ops/s


Even on small or limited platforms, an investment of 8K additonal temporary 
buffer is very cheap and very useful, as it doubles the performance of 
`InputStream::transferTo`, in particular for legacy (non-NIO) applications 
still using `FileInputStream` and `ByteArrayOutputStream`.
I dare to say, even if not proven, that is a very considerable (possibly the 
major) number of existing applications, as NIO was only adopted gradually by 
programmers.

Due to the given reasons, it should be approporiate to change 
`DEFAULT_BUFFER_SIZE` from 8192 to 16384.

-------------

Commit messages:
 - JDK-8299336

Changes: https://git.openjdk.org/jdk/pull/11783/files
 Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=11783&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8299336
  Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod
  Patch: https://git.openjdk.org/jdk/pull/11783.diff
  Fetch: git fetch https://git.openjdk.org/jdk pull/11783/head:pull/11783

PR: https://git.openjdk.org/jdk/pull/11783

Reply via email to