-
Enhancement
-
Resolution: Fixed
-
P4
-
17, 20
-
b20
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8309131 | 17.0.9 | Aleksey Shipilev | P4 | Resolved | Fixed | b01 |
I found out that reading from DataInputStream wrapping ByteArrayInputStream 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
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
- backported by
-
JDK-8309131 Improve performance of DataInputStream
- Resolved
- relates to
-
JDK-5093273 FilterInputStream contains unnecessary volatile: performance hit on SMP machines
- Closed
- links to
-
Commit openjdk/jdk17u-dev/7765ba55
-
Commit openjdk/jdk/74a51ccc
-
Review openjdk/jdk17u-dev/1390
-
Review openjdk/jdk/9956
(1 links to)