2011-11-09 8 views
6

私はhexpatとxml-enumeratorを含むいくつかのHaskell XMLライブラリを使いました。 Real World Haskell(http://book.realworldhaskell.org/read/io.html)のIO章を読んだ後、私は次のコードを実行すると、それを通過するときにガベージコレクションが行われるという印象を受けました。Haskellはメモリが少ないbig xmlファイルを解析します

しかし、私はそれを大きなファイルで実行すると、メモリの使用量はそれが実行されるにつれて上昇し続けます。

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ファイルを解析することです。私は "イベント"を発見したことを通知するために全体の構造を意識する必要はありません。

+1

インタープリタモードで実行するのではなく、コンパイルするときにもこの現象が発生しますか? – hammar

+0

コンパイル時に最適化(-O2)を使用することを忘れないでください。 –

+0

ガベージコレクションのためにコンパイルして最適化する必要がありますか?もしそうなら、私はそれを将来的に試してみることになるでしょう –

答えて

8

私はhexpatのメンテナーです。これはバグです。私は今、hexpat-0.19.8で修正しました。私の注意を引くことに感謝します。

バグはghc-7.2.1で新しくなっています。これは、where句をトリプルにバインドするときには期待していなかったやりとりや、Cとのやりとりをするために必要なunsafePerformIOコードはHaskellで純粋に見えます。

+0

これは私がメンテナーと呼ぶものです。良い仕事黒。 –

3

これはhexpatの問題です。コンパイルを実行し、最適化を行い、ちょうどlengthのような単純なタスクでは、線形メモリが使用されます。

hexpatを見ると、余分なキャッシュが行われていると思います(parseG機能参照)。私はhexpatのメンテナに連絡し、これが期待される動作かどうかを尋ねることをお勧めします。いずれにせよ、haddocksで言及されていたはずですが、リソース消費はライブラリのドキュメントであまりにも頻繁に無視されるようです。

+0

[クイックヒーププロファイル](http://i.stack.imgur.com/8mYdh.png)から、それはほとんどが ' (:) 'コンストラクタです。 – hammar

+0

私の前提が間違っていなかったことを知ってうれしい。私は他のパッケージを使いこなすつもりだと思う。ありがとう! –

関連する問題