【问题标题】:Debugging HXT performance problems调试 HXT 性能问题
【发布时间】:2011-04-04 13:22:17
【问题描述】:

我正在尝试使用 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

我正在尝试读取一个语料库文件,其结构显然类似于&lt;corpus&gt;&lt;sentence&gt;&lt;word form="Hello"/&gt;&lt;word form="world"/&gt;&lt;/sentence&gt;&lt;/corpus&gt;

即使在非常小的开发语料库上,程序也需要大约 15 秒的时间来读取它,其中大约 20% 是 GC 时间(这太多了。)

特别是,大量数据在 DRAG 状态下花费了太多时间。这是个人资料:

监控 DRAG 罪魁祸首。您可以看到 decodeDocument 被调用了很多次,然后它的数据被停止直到执行结束。

现在,我认为这应该可以通过将所有这些 decodeDocument 内容折叠到我的数据结构(SentenceWord)中轻松解决,然后 RT 可以忘记这些 thunk。不过,目前发生的方式是,当我通过在 IO monad 中解构 Either 强制评估时,折叠发生在 very end,它可以很容易发生在线。我看不出有什么理由,而且我试图严格这个程序的尝试到目前为止都是徒劳的。我希望有人可以帮助我:-)

我什至想不出有多少地方可以放seqs 和$!s ……

【问题讨论】:

    标签: performance debugging haskell memory-leaks hxt


    【解决方案1】:

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

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

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

    【讨论】:

    • 嗯,实际上我选择了 HXT 而不是 Hexpat,因为我可以进行相当灵活且定义明确的 XML 解析。我已经编写了一个在线解析器,它在 Hexpat 之上使用 polyParse。这可以完成它的工作,但不像 HXT 那样易于扩展和调试。我会试试 hxt-tagsoup。
    猜你喜欢
    • 2017-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多