BufferedReader & FileReader read () - большой текстовый файл - PullRequest
0 голосов
/ 23 декабря 2018

Я использую следующие 2 кода для чтения большого файла.

Это с использованием FileReader:

File file = new File("/Users/Desktop/shakes.txt");
FileReader reader = new FileReader(file);

int ch;
long start = System.currentTimeMillis();
while ((ch = reader.read()) != -1) {
    System.out.print((char) ch);
}
long end = System.currentTimeMillis();

и последующим использованием BufferedReader:

File file = new File("/Users/Desktop/shakes.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));

int ch;
long start = System.currentTimeMillis();
while ((ch = reader.read()) != -1) {
    System.out.print((char) ch);
}
long end = System.currentTimeMillis();

В соответствии с документацией для BufferedReader:

Поэтому рекомендуется обернуть BufferedReader вокруг любого Reader, чьи операции read () могут быть дорогостоящими, например FileReaders и InputStreamReaders.Без буферизации каждый вызов read () или readLine () может привести к тому, что байты будут считаны из файла, преобразованы в символы и затем возвращены, что может быть очень неэффективно.

С учетом этой документации иразмер буфера по умолчанию 8192 класса BufferedReader, разве общее время чтения файла с BufferedReader не должно быть быстрее?В настоящее время обе части кода работают на моей машине в течение ~ 3000 мс.Однако если я использую readLine в BufferedReader, производительность существенно улучшится (~ 200 мс).

Мысли о чем-то, что мне не хватает?Не ожидается ли, что даже с методом read () BufferedReader будет давать лучшую производительность, чем чтение из FileReader?

Ответы [ 2 ]

0 голосов
/ 23 декабря 2018

Мысли о чем-то, что мне не хватает?

Должно быть быстрее читать файл символ за раз от BufferedReader, чем FileReader.(На порядок!) Поэтому я подозреваю, что проблема в ваших тестах.

  1. В ваших тестах измеряется как чтение файла, так и запись его в стандартный вывод.Таким образом, ваши показатели производительности будут искажены из-за затрат записи файла.И если ваш вывод записывается в «консоль», то эти накладные расходы включают накладные расходы на рисование символов на экране ... и прокрутку.

  2. Ваш тест не учитывает vmнакладные расходы при запуске.

  3. Ваш бенчмарк (очевидно) не влияет на кеширование файлов.(При первом чтении файла он будет прочитан с диска. Если вы вскоре прочитаете его снова, вы можете читать из копии файла, кэшированного в памяти операционной системой.будь быстрее.)

0 голосов
/ 23 декабря 2018

Использование BufferedReader действительно быстрее, чем просто FileReader.

Я выполнил ваш код на своем компьютере со следующим текстовым файлом https://norvig.com/big.txt (6 МБ).

  • Первоначальный результат показывает примерно то же время.Около 17 секунд.
  • Однако это связано с тем, что System.out.print() является узким местом (в цикле).Без печати результат в 4 раза быстрее с BufferedReader.200мс против 50мс.(Сравните это с 17 секундами раньше)

Другими словами, не используйте System.out.print() при тестировании.

Пример

Anулучшенный бенчмарк может выглядеть так, используя StringBuilder.

File file = new File("/Users/Desktop/shakes.txt");
FileReader reader = new FileReader(file);

int ch;
StringBuilder sb = new StringBuilder();
long start = System.currentTimeMillis();
while ((ch = reader.read()) != -1) {
    //System.out.print((char) ch);
    sb.append((char) ch);
}
long end = System.currentTimeMillis();

System.out.println(sb);

Приведенный выше код обеспечивает тот же вывод, но работает намного быстрее.Это точно покажет разницу в скорости при использовании BufferedReader.

...