2011-11-09 51 views
6

所以,我已經使用了幾個Haskell XML庫,包括hexpat和xml-enumerator。在閱讀Real World Haskell中的IO章節後(http://book.realworldhaskell.org/read/io.html),我的印象是,如果我運行下面的代碼,它會在我經歷它時收集垃圾。Haskell解析低內存的大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子句綁定到三元組和unsafePerformIO之間,我需要與C進行交互代碼在Haskell中顯得純粹。

+0

現在,我稱之爲維護者!好的工作blackh。 –

3

這似乎是一個問題與十六進制。運行編譯後的優化,僅用於簡單的任務,如length,會導致線性內存使用。

看着hexpat,我認爲有過多的緩存正在進行(請參閱parseG函數)。我建議聯繫hexpat維護者(s)並詢問這是否是預期的行爲。它應該在haddocks中被提及,但是資源消耗似乎在圖書館文檔中經常被忽略。

+0

從[快速堆配置文件](http://i.stack.imgur.com/8mYdh.png),它看起來大部分來自泄漏' (:)'構造函數。 – hammar

+0

很高興知道我的假設沒有錯。我想我會繼續討論其他軟件包。謝謝! –