Я пытался прочитать данные (символы) из большого текстового файла (~250 МБ) частями по 1 КБ и был очень удивлен, что чтение этого файла с помощью FileReader или BufferedReader занимает одинаковое время, даже несмотря на то, что BufferedReader имеет внутренний буфер символов размером 8 КБ, а FileReader - нет.
Код FileReader:
File file = new File("250mbfile.txt");
FileReader fileReader = new FileReader(file);
char[] charBuffer = new char[1024];
while(fileReader.read(charBuffer, 0, 1024) != -1) {//...};
Код BufferedReader:
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 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
Почему им обоим требуется одинаковое время для выполнения задачи? Поскольку BufferedReader имеет буфер символов размером 8 КБ, насколько я понимаю, он должен вызывать нижележащие операции декодирования InputStreamReader один раз на каждые 8 КБ (он всегда полностью заполняет буфер). FileReader должен делать то же самое один раз на 1 КБ (как указано во фрагментах). Следовательно, FileReader должен работать медленнее, поскольку необходимо вызывать больше операций декодирования. Я могу только предположить, что разница в скорости многократного декодирования блоков размером 1 КБ и декодирования блоков 8 КБ настолько мала, что ее практически невозможно заметить. Чтобы подтвердить это утверждение, я провел два дополнительных измерения JMH:
Из теста «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) {//...};
Из теста «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) {//...};
ДжМХ:
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
Подробнее здесь: https://stackoverflow.com/questions/798 ... ks-of-data