On Thu, 25 Aug 2022 17:31:05 GMT, Brian Burkhalter <[email protected]> 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
>
> src/java.base/share/classes/java/io/RandomAccessFile.java line 78:
>
>> 76: private volatile boolean closed;
>> 77:
>> 78: private final byte[] readBuffer = new byte[8];
>
> As `readBuffer` is used in multiple places without synchronization, doesn't
> this create a race condition?
It does in case one deliberate accesses the same instance from multiple
threads, but there are no thread-safety guarantees for RandomAccessFile. The
same shared buffer approach is used in `DataInputStream` so I think we can use
it here as well.
-------------
PR: https://git.openjdk.org/jdk/pull/10031