2011-11-09 6 views
6

Quindi, ho giocato con diverse librerie XML Haskell, incluso hexpat e xml-enumerator. Dopo aver letto il capitolo di IO in Real World Haskell (http://book.realworldhaskell.org/read/io.html) ho avuto l'impressione che se avessi eseguito il seguente codice, esso verrà raccolto dopo che l'ho passato.Haskell analizza un grande file xml con poca memoria

Tuttavia, quando lo eseguo su un file di grandi dimensioni, l'utilizzo della memoria continua a salire mentre scorre.

runghc parse.hs bigfile.xml 

Cosa sto sbagliando? La mia ipotesi è sbagliata? La mappa/filtro la forza per valutare tutto?

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 

Il mio obiettivo finale è analizzare un enorme file xml con una semplice interfaccia sax. Non voglio essere a conoscenza dell'intera struttura per essere informato che ho trovato un "evento".

+1

Hai questo comportamento anche quando lo compilo piuttosto che eseguirlo in modalità interpretata? – hammar

+0

E non dimenticare di usare l'ottimizzazione (-O2) durante la compilazione. –

+0

Devi compilare e ottimizzare per portarlo alla raccolta dei rifiuti? Se è così, in futuro cercherò di provarlo. –

risposta

8

Sono il manutentore di hexpat. Questo è un bug, che ora ho risolto in hexpat-0.19.8. Grazie per attirarlo alla mia attenzione.

Il bug è nuovo su GHC-7.2.1, ed è a che fare con un'interazione che non mi aspettavo tra un cui vincolante clausola per una tripla, e unsafePerformIO, che ho bisogno di fare l'interazione con la C il codice appare puro in Haskell.

+0

Questo è quello che chiamo un manutentore! Buon lavoro blackh. –

3

Questo sembra essere un problema con hexpat. L'esecuzione compilata, con ottimizzazione e solo per un'attività semplice come length, comporta l'utilizzo della memoria lineare.

Guardando a hexpat, penso che ci sia un eccesso di memorizzazione nella cache in corso (vedere la funzione parseG). Suggerisco di contattare il/i manutentore/i di hexpat e di chiedere se si tratta di un comportamento previsto. Avrebbe dovuto essere menzionato negli eglefini in entrambi i casi, ma il consumo di risorse sembra essere ignorato troppo spesso nella documentazione della biblioteca.

+0

Da [un rapido profilo dell'heap] (http://i.stack.imgur.com/8mYdh.png), sembra che la maggior parte di esso provenga da perdite " (:) 'costruttori. – hammar

+0

Bello sapere che la mia ipotesi non era sbagliata. Immagino che continuerò a scherzare con altri pacchetti. Grazie! –

Problemi correlati