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