2011-11-09 13 views
6

Tak, grałem z kilkoma bibliotekami Haskell XML, w tym heksagonalnym i xml-enumeratorem. Po przeczytaniu rozdziału IO w realnym świecie Haskella (http://book.realworldhaskell.org/read/io.html) miałem wrażenie, że jeśli uruchomię poniższy kod, będzie on zbiorem śmieci podczas jego przechodzenia.Haskell parsować duży plik xml z małą pamięcią

Jednak, gdy uruchomię go na dużym pliku, użycie pamięci stale rośnie, gdy działa.

Co robię źle? Czy moje założenie jest błędne? Czy mapa/filtr wymusza na niej ocenę wszystkiego?

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 

Moim celem końcowym jest przeanalizowanie ogromnego pliku xml za pomocą prostego interfejsu podobnego do sax. Nie chcę być świadomy całej struktury, aby otrzymać powiadomienie, że znalazłem "wydarzenie".

+1

Czy to zachowanie występuje również podczas kompilacji, zamiast uruchamiać je w trybie zinterpretowanym? – hammar

+0

I nie zapomnij użyć optymalizacji (-O2) podczas kompilacji. –

+0

Czy musisz skompilować i zoptymalizować, aby uzyskać go do zbierania śmieci? Jeśli tak, to na pewno spróbuję tego w przyszłości. –

Odpowiedz

8

Jestem opiekunem hexpat. To jest błąd, który teraz naprawiłem w hexpat-0.19.8. Dziękuję za zwrócenie mi uwagi.

Błąd jest nowy na ghc-7.2.1 i ma związek z interakcją, której nie oczekiwałem między klauzulą ​​where wiążącą do potrójnej, a unsafePerformIO, której potrzebuję do interakcji z C kod wydaje się czysty w Haskell.

+0

Teraz to nazywam opiekunem! Dobra robota. –

3

To wydaje się być problem z hexpat. Uruchamianie kompilowane, z optymalizacją, i tylko dla prostego zadania, takiego jak length, powoduje wykorzystanie pamięci liniowej.

Patrząc na hexpat, wydaje mi się, że istnieje nadmierne buforowanie (patrz funkcja parseG). Sugeruję skontaktowanie się z opiekunem (ami) heksafii i pytanie, czy jest to oczekiwane zachowanie. To powinno być wspomniane w łupaczach w obu kierunkach, ale zużycie zasobów wydaje się zbyt często ignorowane w dokumentacji biblioteki.

+0

Z [szybki profil sterty] (http://i.stack.imgur.com/8mYdh.png), wygląda na to, że większość pochodzi z wycieku. (:) 'konstruktorzy. – hammar

+0

Miło wiedzieć, że moje założenie nie było złe. Sądzę, że nadal będę się bawić z innymi pakietami. Dzięki! –