2011-11-09 3 views
6

그래서 저는 hexpat와 xml-enumerator를 포함한 여러 Haskell XML 라이브러리를 가지고 놀았습니다. Real World Haskell (http://book.realworldhaskell.org/read/io.html)의 IO 장을 읽은 후에 다음 코드를 실행하면 가비지 수집이 가능하다는 인상하에있었습니다.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

이제 그것이 내가 메인테이너라고 부르는 것입니다! 좋은 일. –

3

이것은 hexpat의 문제인 것으로 보입니다. 컴파일과 최적화를 실행하고 length과 같은 간단한 작업을 수행하면 선형 메모리가 사용됩니다.

hexpat를 보면 과도한 캐싱이 발생한다고 생각합니다 (parseG 기능 참조). 헥스 패트 관리자에게 연락하여 이것이 예상 된 동작인지 묻는 것이 좋습니다. 그것은 두 가지 방법 모두에서 언급 되었어야했으나 리소스 소모는 라이브러리 설명서에서 너무 자주 무시되는 것처럼 보입니다.

+0

[빠른 힙 프로파일] (http://i.stack.imgur.com/8mYdh.png)에서, 그것의 대부분은' (:)'생성자. – hammar

+0

제 생각을 잘못 이해하지 못했습니다. 나는 다른 꾸러미들과 어슬렁 어슬렁 거릴 것이라고 생각한다. 감사! –

관련 문제