我正在尝试使用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内容折叠到我的数据结构(
Sentence
和Word
)中来轻松解决此问题,然后RT可以忽略这些问题。但是,当前发生的方式是,折叠是在我通过在Either
monad中解构IO
强制进行评估时最终发生的,它很容易在线发生。我认为没有任何理由,到目前为止,我试图严格化该计划的尝试都是徒劳的。我希望有人可以帮助我:-)我什至无法弄清楚将
seq
和$!
放入的太多地方... 最佳答案
可以尝试的一件事:默认的hxt解析器很严格,但是确实存在一个基于tagoup的惰性解析器:http://hackage.haskell.org/package/hxt-tagsoup
了解expat也可以进行延迟处理:http://hackage.haskell.org/package/hxt-expat
您可能想看看切换解析后端本身是否可以解决您的问题。