Какой XML-парсер для Haskell? - PullRequest
10 голосов
/ 26 июня 2009

Я пытаюсь написать приложение, которое выполняет анализ данных, хранящихся в довольно больших XML-файлах (от 10 до 800 МБ). Каждый набор данных хранится в виде одного тега, а конкретные данные указываются как атрибуты. В настоящее время я saxParse из HaXml, и я не удовлетворен использованием памяти при работе с ним. При разборе XML-файла размером 15 МБ он потребляет более 1 ГБ памяти, хотя я старался не хранить данные в списках и обрабатывать их немедленно. Я использую следующий код:

importOneFile file proc ioproc = do
  xml <- readFile file
  let (sxs, res) = saxParse file $ stripUnicodeBOM xml
  case res of
      Just str -> putStrLn $ "Error: " ++ str;
      Nothing -> forM_ sxs (ioproc . proc . (extractAttrs "row"))

где 'proc' - процедура, которая выполняет преобразование данных из атрибутов в запись, и 'ioproc' - процедура, которая выполняет некоторое действие ввода-вывода - вывод на экран, сохранение в базе данных и т. Д.

Как я могу уменьшить потребление памяти при разборе XML? Должно ли помочь переключение на другой анализатор XML?

Обновление: и какой синтаксический анализатор поддерживает различные входные кодировки - utf-8, utf-16, utf-32 и т. Д .?

Ответы [ 2 ]

5 голосов
/ 27 июня 2009

Если вы хотите предположить, что ваши входные данные верны, рассмотрите возможность просмотра TagSoup или Text.XML.Light от людей Галуа.

Они принимают строки в качестве входных данных, поэтому вы можете (косвенно) передавать им все, что Data.Encoding понимает, а именно

  • ASCII
  • UTF8
  • UTF16
  • UTF32
  • KOI8R
  • KOI8U
  • ISO88591
  • GB18030
  • BootString
  • ISO88592
  • ISO88593
  • ISO88594
  • ISO88595
  • ISO88596
  • ISO88597
  • ISO88598
  • ISO88599
  • ISO885910
  • ISO885911
  • ISO885914
  • ISO885915
  • ISO885916
  • CP1250
  • CP1251
  • 1062 * кодировка CP1252 *
  • CP1253
  • CP1254
  • CP1255
  • CP1256
  • CP1257
  • CP1258
  • MacOSRoman
  • JISX0201
  • JISX0208
  • ISO2022JP
  • JISX0212
3 голосов
/ 26 июня 2009

Я не эксперт по Haskell, но то, с чем вы сталкиваетесь, звучит как классическая утечка пространства (то есть ситуация, в которой ленивая оценка Haskell заставляет его резервировать больше памяти, чем необходимо). Возможно, вы сможете решить эту проблему, установив строгость в выводе saxParse.

Есть также хорошая глава по профилированию и оптимизации в Real World Haskell.

РЕДАКТИРОВАТЬ: Найден еще один хороший ресурс по профилированию / нахождении узких мест здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...