Какой самый эффективный способ обработки действительно больших двоичных файлов в Haskell?
Стандартный ответ - прочитать весь файл как ленивый ByteString, а затем использовать что-то вроде бинарного пакета для написания парсера над ним. Есть пара проблем с этим...
Во-первых, библиотеки, такие как Binary, не справляются с синтаксическим разбором, и я явно ожидаю, что синтаксический анализ будет неудачным.
Во-вторых, я не разбираю содержимое всего файла. Я собираюсь пропустить большие куски. И чтение гигабайт данных с диска в ОЗУ только для того, чтобы сборщик мусора отбросить его снова, кажется довольно неэффективным.
В связи с этим мне нужно выяснить, пропускает ли пропуск, который я хочу выполнить, отнимет у меня конец файла или нет (и если ошибка будет отсутствовать).
Мне также может понадобиться искать назад или, может быть, конкретное смещение байта в файле, что, похоже, не очень хорошо поддерживается ленивым подходом ByteString. (Существует серьезная опасность завершения хранения всего файла в ОЗУ.)
Альтернативой, конечно же, является чтение отдельных байтов один за другим, чередующихся с командами hSeek
. Но теперь проблема в том, насколько эффективно чтение файла по одному байту за раз? Похоже, это может быть довольно медленным. Я не уверен, что hSetBuffering
влияет на это. (?)
Тогда, конечно, там mmap
. Но это, похоже, волнует систему виртуальной памяти, если она используется в больших файлах. (Что странно, учитывая, что вся цель для него существует...)
Что мы думаем, ребята? Каков наилучший способ приблизиться к этому, с точки зрения производительности ввода-вывода и поддерживаемости кода?