2011-11-09 21 views
6

Por lo tanto, he jugado con varias bibliotecas Haskell XML, incluyendo hexpat y xml-enumerator. Después de leer el capítulo de IO en Real World Haskell (http://book.realworldhaskell.org/read/io.html), tenía la impresión de que si ejecutaba el siguiente código, sería basura recolectada a medida que avanzaba.Haskell analizar el archivo xml grande con poca memoria

Sin embargo, cuando lo ejecuto en un archivo grande, el uso de memoria sigue subiendo mientras se ejecuta.

runghc parse.hs bigfile.xml 

¿Qué estoy haciendo mal? Es mi suposición incorrecta? ¿El mapa/filtro lo fuerza a evaluar todo?

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 

Mi objetivo final es analizar un gran archivo xml con una interfaz simple similar a un saxofón. No quiero tener que estar al tanto de toda la estructura para recibir notificaciones de que he encontrado un "evento".

+1

¿También obtiene este comportamiento al compilarlo en lugar de ejecutarlo en modo interpretado? – hammar

+0

Y no olvide utilizar la optimización (-O2) al compilar. –

+0

¿Tiene que compilar y optimizar para obtener basura recolectada? Si es así, me aseguraré de probar eso en el futuro –

Respuesta

8

Soy el mantenedor de hexpat. Este es un error, que ahora he reparado en hexpat-0.19.8. Gracias por llamar mi atención.

El error es nuevo en ghc-7.2.1, y tiene que ver con una interacción que no esperaba entre una cláusula where vinculante a una triple, y unaPerformIO insegura, que necesito para hacer la interacción con la C el código aparece puro en Haskell.

+0

¡Ahora eso es lo que llamo mantenedor! Buen trabajo blackh. –

3

Esto parece ser un problema con hexpat. Ejecutando compilado, con optimización, y solo para una tarea simple como length, resulta en uso de memoria lineal.

En cuanto a hexpat, creo que hay un exceso de almacenamiento en caché (ver la función parseG). Sugiero que te pongas en contacto con el/los mantenedor (s) de hexpat y le preguntes si este es el comportamiento esperado. Debería haber sido mencionado en los eglefinos de cualquier manera, pero el consumo de recursos parece ser ignorado con demasiada frecuencia en la documentación de la biblioteca.

+0

De [un perfil rápido de montón] (http://i.stack.imgur.com/8mYdh.png), parece que la mayor parte proviene de fugas ' (:) 'constructores. – hammar

+0

Me alegra saber que mi suposición no era incorrecta. Supongo que seguiré metiéndome con otros paquetes. ¡Gracias! –

Cuestiones relacionadas