Предотвращение утечки пространства при чтении HTML-документа с помощью HXT - PullRequest
1 голос
/ 04 сентября 2010

Ссылка на усеченную версию примера документа

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

concatMap (unwords . take 62 . drop 11) . lines

к тексту и вывести его.

Это занимает более 400 МБ в документе HTML размером 4 МБ, когда я это делаю.

Код, который у меня есть, довольно прост, поэтому я не включаю его из-за боязни смещения ответов.
Вот одна итерация кода:

file = readDocument [(a_validate, v_0), (a_parse_html, v_1)] "Cache entry information.xhtml"
text = fmap last $ runX $
  file >>>
  deep (hasName "pre") />
  isText >>>
--  changeText (unwords . take 62 . drop 11 . lines) >>>
  getText

Я думаю, что проблема в том, что, как я это делаю, HXT пытается сохранить весь текст в памяти при его чтении.

Согласно это кажется, чтоHXT нужно как минимум прочитать весь документ, но не хранить его в памяти.

Я собираюсь попробовать другие парсеры, HaXmL, следующий.
NB Я решил исходную проблемуобрабатывая входной файл как простой текст и желаемую часть, разделенную "<pre>00000000:" и "</pre></body>\n</html>"

Ответы [ 2 ]

1 голос
/ 05 сентября 2010

Является ли анализатор HXT "онлайновым" анализатором?

Пример, который у вас есть, отлично работает для строки, при условии, что каждая строка не патологически длинна: ​​

unwords . take 62 . drop 11 . lines

Здесь вы будете толькопотреблять 73 строки ввода, 11, которые вы отбрасываете, и 62, с которыми вы работаете.Однако этот пример в основном не имеет отношения к обработке XML.Если парсер HXT не является онлайн-парсером, вам придется прочитать весь файл в память, прежде чем вы сможете работать с любыми встроенными строковыми данными.

Боюсь, я не знаю, является ли HXT онлайн-парсером, но это, похоже, суть вашей проблемы.

0 голосов
/ 05 сентября 2010

Попробуйте использовать ByteString модуля Data.Bytestring.Lazy. Обычная строка оптимизирована для рекурсии и ведет себя довольно плохо в случае больших объемов данных. Также вы можете попытаться сделать свои функции более строгими (например, используя seq), чтобы избежать больших накладных расходов из-за неоцененных эффектов. Но будьте осторожны, так как это может ухудшить ситуацию при неправильном применении.

PS: всегда хорошая идея привести краткий пример.

...