1

I read this question : Why is using BufferedInputStream to read a file byte by byte faster than using FileInputStream? According to author BufferedInputStream(BIS) faster than FileInputStream(FIS) because when method read() is invoked in FileInputStream it always does system call using native API in order to fetch single byte, while BufferedInputStream does the same but it requires chunk of bytes from OS and stores them in local field called buf which is declared inside BIS class and then when read() is called BIS return byte from buf array.

I looked through the code of BIS ,specifically read() method and it doesn't clear for me when it happens,when BIS requires chunk of bytes instead of one. Method read() firstly checks if (pos >= count) If so it calls fill() method which firstly checks that buf is not full , if buf has space then method of InputStream is called public int read(byte b[], int off, int len) where b[] is our buffer , and inside of this method we can see that it makes system calls inside loop which is equal to len param .

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

Did i miss something or both classes BIS and FIS will do the same amount of system calls in order to fetch each byte separately ?

Almas Abdrazak
  • 3,209
  • 5
  • 36
  • 80
  • 2
    The answer you linked to continued; *With a BufferedInputStream, the method delegates to an overloaded read() method that reads 8192 amount of bytes and buffers them until they are needed. It still returns only the single byte (but keeps the others in reserve).* It's worth noting that in most cases, your application will be IO bound. Because IO is slow. – Elliott Frisch Nov 21 '19 at 02:15
  • A ByteBuffer which reads in 8196 (8k) chunks is faster. A FileChannel with a 64k ByteBuffer will be even faster (in general). Generally speaking, if you need speed and performance, use a bigger buffer for reading. – markspace Nov 21 '19 at 03:13
  • @markspace I know that it faster but I want to understand why , I want to know how BIS fetches optimize reading chunk of bytes instead of single byte even though I found that it does plenty old read() call in loop – Almas Abdrazak Nov 21 '19 at 03:23
  • The answer is "it's complex." There are optimizations that occur, but they're specific and hard to predict. For example, with higher "demand" in the application (i.e. a larger buffer) the OS will allocate more of its own resources to reading a file, and that speeds up file access. Larger read-ahead buffers are a typical way to speed things up, but it's hard to make specific guess. Basically, "it just is" and it's implementation dependent on other parts of the system why it works that way. – markspace Nov 21 '19 at 03:26
  • @markspace It means that I don't need BIS class because I just can use overloaded version of read method with my own byte array , Am I right ? – Almas Abdrazak Nov 21 '19 at 03:28
  • 1
    BufferedInputStream is code that somebody wrote already, don't re-invent the wheel. If you need exactly the functionality it provides, just use it. – markspace Nov 21 '19 at 03:30

1 Answers1

2

You are looking in the wrong place.

InputStream provides implementation of int read(byte[] b, int off, int len) which indeed invokes read() in a loop. So if a concrete InputStream wrapped by BuffredInputStream does not override this method, then there will be no performance improvement. However, the question you linked talks specifically about FileInputStream which does override this method by invoking native int readBytes(byte b[], int off, int len).

Alex Filatov
  • 4,768
  • 2
  • 16
  • 10