Haskell анализирует большой XML-файл с нехваткой памяти - PullRequest
6 голосов
/ 09 ноября 2011

Итак, я поиграл с несколькими библиотеками на Haskell XML, включая hexpat и xml-enumerator.После прочтения главы IO в реальном мире на Haskell (http://book.realworldhaskell.org/read/io.html) у меня сложилось впечатление, что, если я запущу следующий код, он будет собирать мусор при его выполнении.

Однако, когда я запускаю егобольшой файл, использование памяти продолжает расти.

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-файл с простым саксофонным интерфейсом. Мне не нужно знать всю структуру, чтобы получать уведомления о том, что я нашел «событие».

Ответы [ 2 ]

8 голосов
/ 10 ноября 2011

Я поддерживаю hexpat. Это ошибка, которую я сейчас исправил в hexpat-0.19.8. Спасибо, что обратили на это мое внимание.

Эта ошибка является новой для ghc-7.2.1, и она связана с взаимодействием, которое я не ожидал, между привязкой предложения where к тройке и unsafePerformIO, которое необходимо для взаимодействия с кодом C в Хаскеле выглядят чистыми.

3 голосов
/ 09 ноября 2011

Это похоже на проблему с hexpat.Запуск скомпилированного с оптимизацией и просто для простой задачи, такой как length, приводит к линейному использованию памяти.

Глядя на hexpat, я думаю, что происходит чрезмерное кэширование (см. Функцию parseG),Я предлагаю связаться с сопровождающим (ями) hexpat и спросить, является ли это ожидаемым поведением.Это должно было быть упомянуто в пикшах в любом случае, но потребление ресурсов, кажется, слишком часто игнорируется в документации библиотеки.

...