-
Couldn't load subscription status.
- Fork 38.8k
Description
Zilong Song opened SPR-15762 and commented
The ContentCachingInputStream class has only implemented the int read() method defined in the InputStream class, and inherit all other methods from the super class. Among them, one is the int read(byte[], int, int) method which is often used for reading a batch of bytes.
The default implementation defined in the InputStream only do a repeated call of the int read() method. However, many subclasses of the InputStream provide some more efficient implementations for the int read(byte[], int, int) method, instead of using the default implementation (it is encouraged by the JDK). The following is part of the java doc for the int read(byte[], int, int) method.
The
read(b, off, len)method for classInputStreamsimply calls the methodread()repeatedly. If the first such call results in an IOException, that exception is returned from the call to the intread(b, off, len)method. If any subsequent call toread()results in aIOException, the exception is caught and treated as if it were end of file; the bytes read up to that point are stored into b and the number of bytes read before the exception occurred is returned. The default implementation of this method blocks until the requested amount of input data len has been read, end of file is detected, or an exception is thrown. Subclasses are encouraged to provide a more efficient implementation of this method.
Performance of reading a few bytes from an InputStream with a loop call of the int read() method and a call with the int read(byte[], int, int) method differs a lot. The latter method is much faster than the former method. My code and result for this comparison are listed bellow.
byte[] bytes = new byte[100_000]; // 100k
// test reading an input stream with loop method
ByteArrayInputStream in1 = new ByteArrayInputStream(bytes);
long start = System.nanoTime();
for (int i = 0; i < 100_000; i++) {
in1.read();
}
System.out.println("loop calling cost: " + (System.nanoTime() - start) + "ns");
// test reading the same input stream with batch method
ByteArrayInputStream in2 = new ByteArrayInputStream(bytes);
byte[] buffer = new byte[1000];
int c = 0;
start = System.nanoTime();
while (c < 100_000) {
c += in2.read(buffer);
}
System.out.println("batch calling cost: " + (System.nanoTime() - start) + "ns");Finally, I got the following result on my machine.
loop calling cost: 9158452ns
batch calling cost: 85389ns
Affects: 4.3.9
Referenced from: pull request #1474, and commits d00f6f0, 4d0800f