2009-06-26 19 views
9

Estoy tratando de escribir alguna aplicación que realice análisis de datos almacenados en archivos XML bastante grandes (de 10 a 800 MB). Cada conjunto de datos se almacena como una sola etiqueta, con datos concretos especificados como attrobutes. Actualmente soy saxParse de HaXml, y no estoy satisfecho con el uso de memoria durante el trabajo con él. Al analizar el archivo XML de 15Mb, consume más de 1 Gb de memoria, aunque traté de no almacenar datos en las listas y procesarlo inmediatamente. Yo uso siguiente código:¿Qué analizador XML para Haskell?

importOneFile file proc ioproc = do 
    xml <- readFile file 
    let (sxs, res) = saxParse file $ stripUnicodeBOM xml 
    case res of 
     Just str -> putStrLn $ "Error: " ++ str; 
     Nothing -> forM_ sxs (ioproc . proc . (extractAttrs "row")) 

donde 'proc' - procedimiento, que realiza la conversión de datos de atributos en el expediente, y 'IOProc' - procedimiento, que se realiza alguna acción IO - salida a la pantalla, el almacenamiento de la base de datos, etc.

¿Cómo puedo disminuir el consumo de memoria durante el análisis XML? ¿Debería cambiar a otro analizador XML?

Actualización: ¿y qué analizador es compatible con diferentes codificaciones de entrada - utf-8, utf-16, utf-32, etc.?

Respuesta

4

Si está dispuesto a suponer que sus entradas son válidas, considere mirar TagSoup o Text.XML.Light de la gente de Galois.

estos toman cadenas como entrada, por lo que puede (indirectamente) alimentarlos nada Data.Encoding entiende, a saber

  • ASCII
  • UTF8
  • UTF16
  • UTF32
  • KOI8-R
  • KOI8U
  • ISO88591
  • GB18030
  • Bootstring
  • ISO88592
  • ISO88593
  • ISO88594
  • ISO88595
  • ISO88596
  • ISO88597
  • ISO88598
  • ISO88599
  • ISO885910
  • ISO885911
  • ISO885913
  • ISO885914
  • ISO885915
  • ISO885916
  • CP1250
  • CP1251
  • CP1252
  • CP1253
  • CP1254
  • CP1255
  • CP1256
  • CP1257
  • CP1258
  • MacOSRoman
  • JISX0201
  • JISX0208
  • ISO2022JP
  • JISX0212
3

No soy experto en Haskell, pero lo que te encuentras suena como una fuga de espacio clásica (es decir, una situación en la que la evaluación perezosa de Haskell hace que guarde más memoria de la necesaria). Puede ser capaz de resolverlo forzando rigor en su saxParse output.

También hay un buen capítulo sobre perfiles y la optimización en Real World Haskell.

EDIT: encontrado otro buen recurso de perfiles/hallazgo cuellos de botella here.