RFR: 8265891: (ch) InputStream returned by Channels.newInputStream should override transferTo [v13]

Brian Burkhalter bpb at openjdk.java.net
Thu Aug 12 01:13:32 UTC 2021


On Sun, 1 Aug 2021 22:01:33 GMT, Markus KARG <github.com+1701815+mkarg at openjdk.org> wrote:

>> This PR-*draft* is **work in progress** and an invitation to discuss a possible solution for issue [JDK-8265891](https://bugs.openjdk.java.net/browse/JDK-8265891). It is *not yet* intended for a final review.
>> 
>> As proposed in JDK-8265891, this PR provides an implementation for `Channels.newInputStream().transferTo()` which provide superior performance compared to the current implementation. The changes are:
>> * Prevents transfers through the JVM heap as much as possibly by offloading to deeper levels via NIO, hence allowing the operating system to optimize the transfer.
>> * Using more JRE heap in the fallback case when no NIO is possible (still only KiBs, hence mostl ynegligible even on SBCs) to better perform on modern hardware / fast I/O devides.
>> 
>> Using JMH I have benchmarked both, the original implementation and this implementation, and (depending on the used hardware and use case) performance change was approx. doubled performance. So this PoC proofs that it makes sense to finalize this work and turn it into an actual OpenJDK contribution. 
>> 
>> I encourage everybody to discuss this draft:
>> * Are there valid arguments for *not* doing this change?
>> * Is there a *better* way to improve performance of `Channels.newInputStream().transferTo()`?
>> * How to go on from here: What is missing to get this ready for an actual review?
>
> Markus KARG has updated the pull request incrementally with two additional commits since the last revision:
> 
>  - Draft: Eliminated duplicate code using lambda expressions
>  - Draft: Use blocking mode also for target channel

src/java.base/share/classes/sun/nio/ch/ChannelInputStream.java line 175:

> 173:                     throw new IllegalBlockingModeException();
> 174:                 }
> 175:                 return tls.supply();

It does not look like the `SelectableChannel` branch is tested, including whether an `IllegalBlockingModeException` is thrown when it should be.

src/java.base/share/classes/sun/nio/ch/ChannelInputStream.java line 249:

> 247:     }
> 248: 
> 249:     private static long transfer(ReadableByteChannel src, WritableByteChannel dst) throws IOException {

Does this method have a measurable improvement in performance over `InputStream.transferTo()`?

test/jdk/sun/nio/ch/ChannelInputStream/TransferTo.java line 93:

> 91:         checkTransferredContents(inputStreamProvider, outputStreamProvider, createRandomBytes(1024, 4096));
> 92:         // to span through several batches
> 93:         checkTransferredContents(inputStreamProvider, outputStreamProvider, createRandomBytes(16384, 16384));

Should some random-sized buffers be tested? (Use `jdk.test.lib.RandomFactory` factory for this, not `j.u.Random`. The existing use of `Random` is fine.)

Should some testing be done of streams with non-zero initial position?

test/jdk/sun/nio/ch/ChannelInputStream/TransferTo.java line 101:

> 99:         try (InputStream in = inputStreamProvider.input(inBytes);
> 100:                 OutputStream out = outputStreamProvider.output(recorder::set)) {
> 101:             in.transferTo(out);

The return value of `transferTo()` is not checked.

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

PR: https://git.openjdk.java.net/jdk/pull/4263


More information about the nio-dev mailing list