RFR: 8292698: Improve performance of DataInputStream [v3]

Сергей Цыпанов duke at openjdk.org
Thu Aug 25 07:49:30 UTC 2022


On Sun, 21 Aug 2022 20:07:10 GMT, Сергей Цыпанов <duke at openjdk.org> wrote:

>> I found out that reading from `DataInputStream` wrapping `ByteArrayInputStream` (as well as `BufferedInputStream` or any `InputStream` relying on `byte[]`) can be significantly improved by accessing volatile `in` field only once per operation.
>> 
>> Current implementation does it for each call of `in.read()`, i.e. in `readInt()` method we do it 4 times:
>> 
>> public final int readInt() throws IOException {
>>     int ch1 = in.read();
>>     int ch2 = in.read();
>>     int ch3 = in.read();
>>     int ch4 = in.read();
>>     if ((ch1 | ch2 | ch3 | ch4) < 0)
>>         throw new EOFException();
>>     return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
>> }
>> 
>> Apparently accessing volatile reference with underlying `byte[]` prevents runtime from doing some optimizations, so dereferencing local variable should be more efficient.
>> 
>> Benchmarking:
>> 
>> baseline:
>> 
>> Benchmark                     Mode  Cnt   Score   Error  Units
>> DataInputStreamTest.readChar  avgt   20  22,889 ± 0,648  us/op
>> DataInputStreamTest.readInt   avgt   20  21,804 ± 0,197  us/op
>> 
>> patch:
>> 
>> Benchmark                     Mode  Cnt   Score   Error  Units
>> DataInputStreamTest.readChar  avgt   20  11,018 ± 0,089  us/op
>> DataInputStreamTest.readInt   avgt   20   5,608 ± 0,087  us/op
>
> Сергей Цыпанов has updated the pull request incrementally with one additional commit since the last revision:
> 
>   8292698: Fix copyright year

Btw, I've tried to reimplement `readInt()` in a way similar to `readLong()`:

public final int readInt() throws IOException {
    readFully(readBuffer, 0, 4);
    return (readBuffer[0] & 0xff) << 24
         + (readBuffer[1] & 0xff) << 16
         + (readBuffer[2] & 0xff) << 8
         + (readBuffer[3] & 0xff);
}

but with this change the build fails with

Building target 'test' in configuration 'macosx-x86_64-server-release'
Compiling 3158 files for java.base
Updating support/src.zip
Optimizing the exploded image
Error occurred during initialization of boot layer
java.lang.module.FindException: Error reading module: /Users/stsypanov/IdeaProjects/jdk/build/macosx-x86_64-server-release/jdk/modules/java.management.rmi
Caused by: java.lang.module.InvalidModuleDescriptorException: Bad magic number
make[3]: *** [/Users/stsypanov/IdeaProjects/jdk/build/macosx-x86_64-server-release/jdk/_optimize_image_exec.marker] Error 1
make[2]: *** [exploded-image-optimize] Error 2

ERROR: Build failed for target 'test' in configuration 'macosx-x86_64-server-release' (exit code 2) 
Stopping sjavac server

=== Output from failing command(s) repeated here ===
* For target jdk__optimize_image_exec:
Error occurred during initialization of boot layer
java.lang.module.FindException: Error reading module: /Users/stsypanov/IdeaProjects/jdk/build/macosx-x86_64-server-release/jdk/modules/java.management.rmi
Caused by: java.lang.module.InvalidModuleDescriptorException: Bad magic number

* All command lines available in /Users/stsypanov/IdeaProjects/jdk/build/macosx-x86_64-server-release/make-support/failure-logs.
=== End of repeated output ===

What is wrong with the change?

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

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


More information about the core-libs-dev mailing list