我正在尝试使用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状态下花费了太多时间。这是个人资料:

监视DRAG罪魁祸首。您会看到,decodeDocument被调用很多,然后其数据将停滞,直到执行结束。

现在,我认为应该通过将所有那些decodeDocument内容折叠到我的数据结构(SentenceWord)中来轻松解决此问题,然后RT可以忽略这些问题。但是,当前发生的方式是,折叠是在我通过在Either monad中解构IO强制进行评估时最终发生的,它很容易在线发生。我认为没有任何理由,到目前为止,我试图严格化该计划的尝试都是徒劳的。我希望有人可以帮助我:-)

我什至无法弄清楚将seq$!放入的太多地方...

最佳答案

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

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

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

10-08 10:48