3

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 状態で長時間を費やしています。これはプロフィールです:

http://imgur.com/YC3jh

DRAGの犯人を監視しています。decodeDocument が頻繁に呼び出され、そのデータが実行の最後まで停止していることがわかります。

これは、decodeDocument のすべてをデータ構造 (SentenceおよびWord) に折りたたむことで簡単に修正でき、RT はこれらのサンクを忘れることができると思います。ただし、現在発生している方法は、オンラインで簡単に発生する可能性のあるモナドでの脱構築による評価を強制すると、最後 折り畳みが発生することです。これには理由が見当たらず、プログラムを厳格化しようとする私の試みはこれまでのところ無駄でした。誰かが私を助けてくれることを願っています:-)EitherIO

seqs とsを入れる場所が多すぎてわかりません$!…</p>

4

1 に答える 1

1

試してみるべき 1 つの可能性: デフォルトの hxt パーサーは厳密ですが、tagsoup に基づく遅延パーサーが存在します: http://hackage.haskell.org/package/hxt-tagsoup

expatも遅延処理を行うことができることを理解してください:http://hackage.haskell.org/package/hxt-expat

解析バックエンドを切り替えるだけで問題が解決するかどうかを確認したい場合があります。

于 2011-04-04T14:26:43.403 に答える