On Wed, 2 Jun 2021 09:03:03 GMT, Alan Bateman <al...@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?
>
> src/java.base/share/classes/java/nio/channels/Channels.java line 145:
> 
>> 143:      * @since 18
>> 144:      */
>> 145:     public static class ChannelOutputStream extends OutputStream {
> 
> This adds Channels.ChannelOutputStream to the API, you will need to justify 
> that.

You mean as a source comment or just here in this discussion thread?

In fact it might be better to not add it to a package with is part of the API, 
but to move it to the `sun` package, which is not, right?

The justification is that I need to refer to this class from 
`ChannelInputStream::transferTo()` to be able to get hold of this previously 
anonymous class's inner member "ch", which in turn is key to the whole story of 
this PR: Using NIO transfer between the channels instead of moving bytes 
through the JVM's memory.

> src/java.base/share/classes/sun/nio/ch/ChannelInputStream.java line 148:
> 
>> 146: 
>> 147:     @Override
>> 148:     public long transferTo(final OutputStream out) throws IOException {
> 
> Please try to keep to existing style, e.g. most/all "final" are noise and can 
> be removed.

Sorry I am new do this project and didn't know that final is banned generally. 
To get it right: Is it banned only in parameters or also for variables and 
class members?

> src/java.base/share/classes/sun/nio/ch/ChannelInputStream.java line 158:
> 
>> 156:                 for (long n = size - pos; i < n;
>> 157:                   i += fc.transferTo(pos + i, Long.MAX_VALUE, oc));
>> 158:                 fc.position(size);
> 
> The patch is improving but needs cleanup so that it is easy to maintain. I 
> think I would move the I/O ops out of the update code and into the for 
> statement/block. Also this will need the update to the channel position to be 
> a finally block so that the it is adjusted when there are partial transfers.

Moved I/O operations into the `for` statement by 
https://github.com/openjdk/jdk/pull/4263/commits/562b1023e62c4ff0a36e55ebc119cee6fb69809c.

> src/java.base/share/classes/sun/nio/ch/ChannelInputStream.java line 177:
> 
>> 175:                 }
>> 176: 
>> 177:                 final var bb = ByteBuffer.allocateDirect(TRANSFER_SIZE);
> 
> This will probably need to be changed to the use the TL buffer cache.

Uhm... Maybe this is a dumb beginner's question, but: What is "the TL buffer 
cache"?

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

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

Reply via email to