RFR: 8292937: Improve performance of some read operations of RandomAccessFile [v5]
Alan Bateman
alanb at openjdk.org
Sat Aug 27 06:56:10 UTC 2022
On Fri, 26 Aug 2022 20:59:57 GMT, Сергей Цыпанов <duke at openjdk.org> wrote:
>> Currently some operations of RandomAccessFile are implemented with multiple read() invocations:
>>
>> public final int readInt() throws IOException {
>> int ch1 = this.read();
>> int ch2 = this.read();
>> int ch3 = this.read();
>> int ch4 = this.read();
>> if ((ch1 | ch2 | ch3 | ch4) < 0)
>> throw new EOFException();
>> return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
>> }
>>
>> This can be improved by using bulk reads:
>>
>> public final int readInt() throws IOException {
>> readFully(readBuffer, 0, 4);
>> return Bits.getInt(readBuffer, 0);
>> }
>>
>> Benchmarking:
>>
>> baselile
>> Benchmark (kiloBytes) Mode Cnt Score Error Units
>> RandomAccessFileReadBenchmark.readInt 1 avgt 10 1060,526 ± 62,036 us/op
>> RandomAccessFileReadBenchmark.readInt 5 avgt 10 5745,671 ± 1374,277 us/op
>> RandomAccessFileReadBenchmark.readLong 1 avgt 10 1399,494 ± 378,072 us/op
>> RandomAccessFileReadBenchmark.readLong 5 avgt 10 4864,425 ± 329,282 us/op
>> RandomAccessFileReadBenchmark.readShort 1 avgt 10 1111,163 ± 70,883 us/op
>> RandomAccessFileReadBenchmark.readShort 5 avgt 10 4933,058 ± 339,273 us/op
>>
>> patch
>> Benchmark (kiloBytes) Mode Cnt Score Error Units
>> RandomAccessFileReadBenchmark.readInt 1 avgt 10 311,404 ± 17,337 us/op
>> RandomAccessFileReadBenchmark.readInt 5 avgt 10 1210,381 ± 22,742 us/op
>> RandomAccessFileReadBenchmark.readLong 1 avgt 10 201,726 ± 8,885 us/op
>> RandomAccessFileReadBenchmark.readLong 5 avgt 10 667,117 ± 6,779 us/op
>> RandomAccessFileReadBenchmark.readShort 1 avgt 10 560,259 ± 16,783 us/op
>> RandomAccessFileReadBenchmark.readShort 5 avgt 10 2251,975 ± 54,533 us/op
>
> Сергей Цыпанов has updated the pull request incrementally with two additional commits since the last revision:
>
> - 8292937: Fix error C2057
> - 8292937: Remove unused method
src/java.base/share/native/libjava/io_util.c line 108:
> 106: ((*(buf + 6) & 0xFF) << 8) +
> 107: ((*(buf + 7) & 0xFF)));
> 108: }
Doing this in a JNI method is problematic for several reasons and I think we should try to keep the JNI methods as simple/short as possible, ideally map to a single syscall and not do too much if possible. In the medium/long term then many of the native methods in this area will be replaced anyway, maybe by re-implementing RAF/etc. on NIO, maybe by replacing the JNI code with the java.lang.foreign APIs. In addition, I expect there will be another tranche of changes that will significantly change this code for virtual threads to allow the underlying thread be released when doing for file I/O.
-------------
PR: https://git.openjdk.org/jdk/pull/10031
More information about the core-libs-dev
mailing list