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
IO
seq
s とsを入れる場所が多すぎてわかりません$!
…</p>