6

そこで、hexpat や xml-enumerator など、いくつかの Haskell XML ライブラリをいじってみました。Real World Haskell (http://book.realworldhaskell.org/read/io.html) の IO の章を読んだ後、次のコードを実行するとガベージ コレクションが行われるという印象を受けました。

ただし、大きなファイルで実行すると、実行中にメモリ使用量が増え続けます。

runghc parse.hs bigfile.xml

私は何を間違っていますか?私の仮定は間違っていますか?マップ/フィルターは強制的にすべてを評価しますか?

import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString.Lazy.UTF8 as U
import Prelude hiding (readFile)
import Text.XML.Expat.SAX 
import System.Environment (getArgs)

main :: IO ()
main = do
    args <- getArgs
    contents <- BSL.readFile (head args)
    -- putStrLn $ U.toString contents
    let events = parse defaultParseOptions contents 
    mapM_ print $ map getTMSId $ filter isEvent events

isEvent :: SAXEvent String String -> Bool 
isEvent (StartElement "event" as) = True
isEvent _ = False

getTMSId :: SAXEvent String String -> Maybe String
getTMSId (StartElement _ as) = lookup "TMSId" as

私の最終的な目標は、単純なサックスのようなインターフェイスで巨大な xml ファイルを解析することです。「イベント」を見つけたという通知を受け取るために、構造全体を意識する必要はありません。

4

2 に答える 2

8

私はhexpatのメンテナーです。これはバグで、hexpat-0.19.8 で修正済みです。私の注意を引いてくれてありがとう。

このバグは ghc-7.2.1 で新たに発生したもので、トリプルにバインディングする where 節と unsafePerformIO の間で予期していなかった相互作用に関係しています。ハスケル。

于 2011-11-10T12:42:18.630 に答える
3

これは hexpat の問題のようです。最適化を使用してコンパイルして実行し、 などの単純なタスクのみを実行するとlength、メモリの使用量が線形になります。

hexpat を見ると、過剰なキャッシングが行われていると思います (parseG関数を参照)。hexpat のメンテナーに連絡して、これが予期された動作かどうかを尋ねることをお勧めします。どちらの方法でもハドックで言及されているはずですが、ライブラリのドキュメントではリソース消費が無視されることが多すぎるようです。

于 2011-11-09T18:47:42.077 に答える