我正在尝试使用 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 可以忘记这些 thunk。它目前发生的方式是,折叠发生在最后,当我通过在monad 中解构来强制评估时,它很 容易在online中发生。我看不出有什么理由,而且我试图严格这个程序的尝试到目前为止都是徒劳的。我希望有人可以帮助我:-)Either
IO
我什至想不出太多的地方可以放seq
s 和$!
s...</p>