Я хочу как можно быстрее прочитать все строки размером в 1 ГБ в Stream<String>
. В настоящее время я использую Files(path).lines()
для этого. После разбора файла я делаю несколько вычислений (map()
/filter()
)
Сначала я думал, что это уже сделано параллельно, но, похоже, я ошибаюсь:
При чтении файла, как он есть, он занимает около 50 секунд на моем ноутбуке с двумя процессорами.
Однако, если я разделяю файл с помощью команд bash, а затем обрабатываю их параллельно, это занимает всего около 30 секунд.
Я попробовал следующие комбинации:
- отдельный файл, нет параллельных строк() stream ~ 50 секунд
- один файл,
Files(..).lines().parallel().[...]
~ 50 секунд - два файла, не параллельные строки() strean ~ 30 секунд
- два файла,
Files(..).lines().parallel().[...]
~ 30 секунд
Я запускал эти четыре раза с примерно одинаковыми результатами (на 1 или 2 секунды). [...]
представляет собой цепочку только для отображения и фильтра, а в конце - toArray(...)
для запуска оценки.
Вывод состоит в том, что нет разницы в использовании lines().parallel()
. Поскольку чтение двух файлов параллельно занимает более короткое время, выигрыш в производительности от разделения файла. Однако кажется, что весь файл читается серийно.
Edit:
Я хочу указать, что я использую SSD, поэтому есть практически время поиска. Файл содержит 1658652 (относительно короткие) строки.
Разделение файла в bash занимает около 1,5 секунд:
time split -l 829326 file # 829326 = 1658652 / 2
split -l 829326 file 0,14s user 1,41s system 16% cpu 9,560 total
Итак, мой вопрос: есть ли какой-либо класс или функция в Java 8 JDK, который может распараллелить чтение всех строк, не разбивая их первым? Например, если у меня два ядра ЦП,
первый считыватель строк должен начинаться с первой строки, а второй - в строке (totalLines/2)+1
.