Какой самый быстрый способ чтения целых чисел из файла на Java? - PullRequest
2 голосов
/ 24 мая 2011

У меня есть файл целых чисел, расположенных так:

1 2 3 55 22 11 (and so on)

И я хочу читать эти цифры как можно быстрее, чтобы уменьшить общее время выполнения моей программы. Пока я использую сканер с хорошими результатами. Однако я чувствую, что существует более быстрая утилита ввода-вывода, которую я могу использовать. Кто-нибудь может указать мне правильное направление?

EDIT:

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

Ответы [ 3 ]

9 голосов
/ 24 мая 2011

Текущий формат файла

Если числа представлены как Strings, более быстрого способа их чтения и анализа нет, дисковый ввод-вывод будет порядкаВеличина медленнее, чем все, что делает процессор.Единственное, что можно сделать, это использовать BufferedReader с огромным размером буфера и попытаться получить столько же, если не весь файл в памяти, перед использованием Scanner.

Альтернативный формат файла

Если вы можете представить их в виде двоичного файла в файле и прочитать числа при использовании DataInputStream класса , то вы можете получить небольшое уменьшение времени ввода-вывода и предельноеУменьшение ЦП, потому что вам не нужно анализировать представление String в int, которое, вероятно, не поддается измерению, если ваш входной файл не будет в сотнях мегабайт или больше.** Буферизация входного потока все равно будет иметь больший эффект, чем что-либо еще, в этом случае используйте BufferedInputStream.

Как оптимизировать

Вам необходимо надежное профилирование длядаже определить, влияют ли внесенные вами изменения на производительность положительно или отрицательно .

Такие вещи, как кэширование диска ОС, будут искажать тесты, если вы снова и снова читаете один и тот же файл, ОС кеширует его и испортит ваши тесты.Узнайте, что достаточно хорошо раньше, чем позже.

"Мы должны забыть о малой эффективности, скажем, в 97% случаев: преждевременная оптимизация - это«корень зла» - Дональд Кнут

* * * * * * * * * * * * * * * * * * * * * * 1045] * * * * * * * * * * * Часть цитаты Кунта является важной, это означает:

Не оптимизируйте без профилирования и тестов, чтобы убедиться, что то, что вы изменяете, является узким местом и что вы можете измерить положительное или отрицательное влияние ваших изменений.

Вотбыстрый тест , сравнивающий BufferedInputStream, считывающий тот же набор двоичных чисел, с Scanner, подкрепленный BufferedReader, читающим тот же набор чисел, что и текстовые представления с разделителем SPACE.

результаты довольно постоянны:

Для 1000 номеров на моем ноутбуке Core i3 с 8 ГБ ОЗУ

Read binary file in 0001 ms
Read text file in   0041 ms

Для 1 000 000 номеров на моем ноутбуке Core i3 с 8 ГБRAM

Read binary file in 0603 ms
Read text file in   1509 ms

Для 50 000 000 номеров на моем ноутбуке Core i3 с 8 ГБ ОЗУ

Read binary file in 29020 ms
Read text file in   70346 ms

Размеры файлов для 50 000 000 номеров были следующими:

 48M input.dat
419M input.txt

Чтение двоичного кода происходит намного быстрее, пока набор чисел не станет очень большим.Количество операций ввода-вывода для двоично-кодированных целых чисел меньше (примерно в 10 раз), отсутствует логика синтаксического анализа String и другие затраты на создание объекта и все остальное, что делает Scanner.Я пошел дальше и использовал Buffered версии классов InputStream и Reader, потому что это лучшие практики и их следует использовать при любой возможности.

. Для дополнительной поддержки сжатие уменьшит время ожидания ввода-вывода для больших файлов, практически не влияя на процессорное время.

1 голос
/ 24 мая 2011

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

Для формата, который вы используете, я бы сжал файлы и прочитал сжатые данные.Это простой способ повысить скорость чтения базовых данных.

0 голосов
/ 24 мая 2011

Возможности эскалации:

  • Купить более быстрый диск.
  • Купить ssd-диск.
  • Сохранить файл на виртуальном диске.

Всегда есть компромисс в получении большей производительности / скорости.Вышеуказанные методы будут стоить денег и должны выполняться на каждом хосте, так что, если это программа, которая продается нескольким клиентам, может быть лучше выбрать алгоритм, который сэкономит деньги на каждом хосте,Программа запущена.

Если вы сжимаете файл или сохраняете двоичные данные, скорость чтения увеличивается, но будет сложнее проверять данные с помощью независимых инструментов.Конечно, мы не можем сказать, как часто это может происходить.

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

А может быть, это просто упражнение, чтобы выяснить, как быстро вы можете получить.Но затем я хотел бы предостеречь от привычки всегда достигать максимальной производительности без учета компромиссов и затрат.

...