Отладка проблем с производительностью HXT - PullRequest
3 голосов
/ 04 апреля 2011

Я пытаюсь использовать HXT для чтения некоторых больших файлов данных XML (сотни МБ).

Мой код имеет утечку пространства где-то , но я не могукажется, нашел это.Я немного разбираюсь в том, что происходит, благодаря моим очень ограниченным знаниям о цепочке инструментов профилирования ghc.

По сути, документ анализируется, но не оценивается.

Вот некоторый код:

{-# LANGUAGE Arrows, NoMonomorphismRestriction #-}

import Text.XML.HXT.Core
import System.Environment (getArgs)
import Control.Monad (liftM)

main = do file <- (liftM head getArgs) >>= parseTuba
          case file of(Left  m) -> print "Failed."
                      (Right _) -> print "Success."

data Sentence t = Sentence [Node t] deriving Show
data Node t = Word { wSurface :: !t } deriving Show

parseTuba :: FilePath -> IO (Either String ([Sentence String]))
parseTuba f = do r <- runX (readDocument [] f >>> process)
                 case r of
                      []   -> return $ Left "No parse result."
                      [pr] -> return $ Right pr
                      _    -> return $ Left "Ambiguous parse result!"

process :: (ArrowXml a) => a XmlTree ([Sentence String])
process = getChildren >>> listA (tag "sentence" >>> listA word >>> arr (\ns -> Sentence ns))

word :: (ArrowXml a) => a XmlTree (Node String)
word = tag "word" >>> getAttrValue "form" >>> arr (\s -> Word s)

-- | Gets the tag with the given name below the node.
tag  :: (ArrowXml a) => String -> a XmlTree XmlTree
tag s = getChildren >>> isElem >>> hasName s

Я пытаюсь прочитать файл корпуса, и структура, очевидно, похожа на <corpus><sentence><word form="Hello"/><word form="world"/></sentence></corpus>.

Даже на очень маленьком корпусе разработки программасчитывание занимает ~ 15 секунд, из которых около 20% - это время GC (это слишком много).

В частности, много данных тратят слишком много времени в состоянии DRAG.Это профиль:

http://imgur.com/YC3jh

мониторинг преступников DRAG.Вы можете видеть, что decodeDocument часто вызывается, и его данные затем останавливаются до самого конца выполнения.

Теперь, я думаю, это легко исправить, сложив все эти вещи decodeDocument в мои структуры данных (Sentence и Word) и тогда РТ может забыть об этих громах.Однако в настоящее время происходит то, что свертывание происходит в очень end , когда я форсирую вычисление деконструкцией Either в монаде IO, где это может легко произойти онлайн .Я не вижу причин для этого, и мои попытки ужесточить программу до сих пор были тщетными.Я надеюсь, что кто-нибудь может мне помочь: -)

Я просто не могу даже найти слишком много мест, чтобы положить seq с и $! с в ...

1 Ответ

1 голос
/ 04 апреля 2011

Можно попробовать одну вещь: hxt-анализатор по умолчанию строгий, но существует существует ленивый анализатор на основе tagoup: http://hackage.haskell.org/package/hxt-tagsoup

В понимании, что expat может выполнять ленивую обработкуа также: http://hackage.haskell.org/package/hxt-expat

Возможно, вы захотите узнать, решает ли сама по себе переключение разбора бэкэндов.

...