I was trying to read data (chars) from a large text file (~250MB) in 1KB chunks and was very surprised that reading that file using either FileReader or BufferedReader takes exactly the same time, even though the BufferedReader has an internal 8KB character buffer, while FileReader doesn't.
FileReader code:
File file = new File("250mbfile.txt");
FileReader fileReader = new FileReader(file);
char[] charBuffer = new char[1024];
while(fileReader.read(charBuffer, 0, 1024) != -1) {//...};
BufferedReader code:
File file = new File("250mbfile.txt");
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
char[] charBuffer = new char[1024];
while(bufferedReader.read(charBuffer, 0, 1024) != -1) {//...};
JMH benchmark:
Benchmark Mode Cnt Score Error Units
Benchmark.bufferedReaderCHARBUFFER avgt 5 3878.794 ± 145.105 ms/op
Benchmark.fileReaderCHARBUFFER avgt 5 3968.835 ± 160.128 ms/op
Why do they both take the same time to complete the task? Since BufferedReader has an 8K character buffer, as I understand, it has to invoke underlaying InputStreamReader's decoding operations once per 8K bytes (it always fills the buffer fully). FileReader has to do the same once per 1K bytes (as specified in the snippets). Therefore, FileReader should be slower as more decoding operations have to be invoked. My only guess would be that the difference in the speeds of repeatedly decoding 1K blocks of bytes and decoding 8K blocks of bytes is so extremely tiny that it's basically impossible to notice. To support this claim, I've made two additional JMH measurements:
From the test "CHARBUFFER_1K":
File file = new File("250mbfile.txt");
FileReader fileReader = new FileReader(file);
char[] charBuffer = new char[1024];
while(fileReader.read(charBuffer, 0, 1024) != -1) {//...};
From the test "CHARBUFFER_8K":
File file = new File("250mbfile.txt");
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
char[] charBuffer = new char[8192];
while(bufferedReader.read(charBuffer, 0, 8192) != -1) {//...};
JMH:
Benchmark Mode Cnt Score Error Units
Benchmark.CHARBUFFER_8K avgt 5 3778.331 ± 143.736 ms/op
Benchmark.CHARBUFFER_1K avgt 5 3778.793 ± 134.118 ms/op