3

我正在尝试使用 HXT 读取一些大型 XML 数据文件(数百 MB。)

我的代码在某处有空间泄漏,但我似乎找不到它。由于我对 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 内容折叠到我的数据结构(SentenceWord)中来轻松解决,然后 RT 可以忘记这些 thunk。它目前发生的方式是,折叠发生在最后,当我通过在monad 中解构来强制评估时,它 容易在online中发生。我看不出有什么理由,而且我试图严格这个程序的尝试到目前为止都是徒劳的。我希望有人可以帮助我:-)EitherIO

我什至想不出太多的地方可以放seqs 和$!s...</p>

4

1 回答 1

1

可以尝试的一件事:默认的 hxt 解析器是严格的,但确实存在基于 tagoup 的惰性解析器:http: //hackage.haskell.org/package/hxt-tagsoup

了解 expat 也可以进行惰性处理:http ://hackage.haskell.org/package/hxt-expat

您可能想看看切换解析后端本身是否可以解决您的问题。

于 2011-04-04T14:26:43.403 回答