Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance when Reading single byte vs many at a time?

I'm trying to compare InputStream.read() vs InputStream.read(byte[] b) in terms of performance.

Is InputStream.read(byte[] b) faster in some way, given the read(b, off, len) method for class InputStream simply calls the method read() repeatedly?

like image 982
Ashish Kataria Avatar asked Jul 16 '12 09:07

Ashish Kataria


2 Answers

You shouldn't confuse what is the default behaviour of InputStream and what most of its subclasses do. A principle of OO design is that sub-classes can change the behaviour of a method for that implementation.

From InputStream - read(byte[]) calls read() repeatedly.

public int read(byte b[], int off, int len) throws IOException {
   // code removed

        for (; i < len ; i++) {
            c = read();

   // code removed
}

From BufferedInputStream - read(byte[]) does not call read().

public synchronized int read(byte b[], int off, int len) throws IOException {
   // code removed
        int nread = read1(b, off + n, len - n);
   // code removed
}

private int read1(byte[] b, int off, int len) throws IOException {
   // code removed
            return getInIfOpen().read(b, off, len);
   // code removed
}

From FileInputStream - read(byte[]) does not call read().

public int read(byte b[], int off, int len) throws IOException {
    return readBytes(b, off, len);
}

private native int readBytes(byte b[], int off, int len) throws IOException;

While InputStream will read one byte at a time, almost all the implementations will pass read(byte[]) to the same method in the underlying stream.

Note: the implementations for read(byte[], int, int) are different in all three cases.

What i mean to ask more clearly is: Let's say i want to read 20 bytes, Reading one byte at a time will hit underlying stream (e.g. file system) every time in a loop that means 20 times..ok Now reading array of 20 bytes in one go, i.e using read(byte[] 20), Now that's gonna hit underlying stream (e.g. file system) one time or 20 times..?? (as it's given: read(byte[] b) method is also going to call the method read() repeatedly 20 times) ??

Whether you use BufferedInputStream or FileInputStream, one read(byte[]) results in atmost one system call to read into the byte[].

like image 124
Peter Lawrey Avatar answered Sep 28 '22 20:09

Peter Lawrey


Use whichever you find most convenient in your case but remember to wrap your InputStream with BufferedInputStream.

Without buffering single read() will hit underlying stream (e.g. file system) every time you read. With buffering the same read() loads a chunk (e.g. 4KiB) and buffers it. Obviously reading from disk (even if some lower-lever OS/hard disk caching is present) is much slower.

Therefore read(byte[] b) is better only if your stream is not buffered - or if you really want to read more than one byte.

like image 40
Tomasz Nurkiewicz Avatar answered Sep 28 '22 20:09

Tomasz Nurkiewicz