我试图使用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时间(这太过了)。
特别是,很多数据在拖放状态下花费了太多的时间。以下是简介:

监视拖曳罪犯。您可以看到,decodeDocument经常被调用,然后它的数据被停止,直到执行结束。
现在,我认为应该很容易地通过将所有这些decodeDocument内容折叠到我的数据结构(Sentence和Word)中来解决这个问题,然后RT就可以忘记这些块了。但是,目前的情况是,当我在IO monad中解构IO时,折叠发生在最后,在那里它可以很容易地发生在网上。我看不出有什么理由这样做,到目前为止,我试图严格限制这个项目的努力都是徒劳的。我希望有人能帮我:)
我只是想不出有多少地方可以把seq和$!放在…里
发布于 2011-04-04 14:26:43
尝试一件可能的事情:默认的hxt解析器是严格的,但是确实存在一个基于标签汤的惰性解析器:http://hackage.haskell.org/package/hxt-tagsoup。
在理解外派也可以做懒惰的处理:http://hackage.haskell.org/package/hxt-expat
您可能想看看切换解析后端本身是否解决了您的问题。
https://stackoverflow.com/questions/5539092
复制相似问题