Подтвердить что ты не робот

Как получить доступ прямо и эффективно к очень большому текстовому файлу?

У меня есть очень большие текстовые файлы (+ 10 ГБ), которые я хочу прочитать для некоторых технологий интеллектуального анализа данных. Для этого я использую параллельную технику с MPI, поэтому многие процессы могут получить доступ к одному файлу.
На самом деле, я хочу, чтобы каждый процесс читал N количество строк. Поскольку файл не структурирован (одинаковое количество полей, но каждое поле может содержать различное количество символов), я обязан разбирать файл и не параллелен, и это занимает много времени. Есть ли способ прямого доступа к определенному числу строк с синтаксическим разбором и подсчетом строк? Спасибо, что помогли.

4b9b3361

Ответ 1

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

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

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

Затем вы можете отключить параллельные задачи на каждом из идентифицированных фрагментов.

Ответ 2

Несколько других вариантов, помимо упомянутых здесь, которые не требуют сканирования всего файла:

  • сделать мастер-процесс, который толкает строки через pipe/fifos к дочерним процессам, которые выполняют фактическую обработку. Это может быть немного медленнее, но если говорить, что 90% времени, проведенного в подпроцессах, является фактическим хрустом текстов, это должно быть хорошо.

  • Глупый, но эффективный трюк: скажем, у вас есть N процессов, и вы можете сказать каждому процессу argv или что-то вроде "серийного номера", например. processor -serial_number [1|2|3...N] -num_procs N, все они могут прочитать одни и те же данные, но обрабатывать только строки, имеющие lineno % num_procs == serial_number. это немного менее эффективно, потому что все они будут читать все данные, но опять же, если они работают только на каждой N-й строке, и это то, что потребляет большую часть времени, вы должны быть в порядке.

Ответ 3

Нет, нет: пока вы не прочитаете неизвестные данные, никто не узнает, сколько там новых символов строки. Эта сложность проблемы - O (n), что означает, что по крайней мере один раз вам придется прочитать весь файл. Затем вы можете создать таблицу индексов, в которой вы записываете, где есть новые строковые символы в вашем файле: это может использоваться всеми процессами, а с помощью fseek вы можете значительно ускорить дальнейший доступ.