6

因此,我使用了几个 Haskell XML 库,包括 hexpat 和 xml-enumerator。在阅读了 Real World Haskell (http://book.realworldhaskell.org/read/io.html) 中的 IO 章节后,我的印象是,如果我运行以下代码,在我浏览它时它会被垃圾收集。

但是,当我在一个大文件上运行它时,内存使用量会随着它的运行而不断攀升。

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

我的最终目标是用一个简单的类似 sax 的界面来解析一个巨大的 xml 文件。我不想知道整个结构才能得到通知我发现了一个“事件”。

4

2 回答 2

8

我是 hexpat 的维护者。这是一个错误,我现在已在 hexpat-0.19.8 中修复。感谢您引起我的注意。

该错误是 ghc-7.2.1 上的新错误,它与我没想到的 where 子句绑定到三元组和 unsafePerformIO 之间的交互有关,我需要使与 C 代码的交互看起来纯哈斯克尔。

于 2011-11-10T12:42:18.630 回答
3

这似乎是 hexpat 的问题。运行已编译、优化并仅用于简单任务,例如length,导致线性内存使用。

查看 hexpat,我认为缓存过多(请参阅parseG函数)。我建议联系 hexpat 维护者并询问这是否是预期的行为。无论哪种方式,黑线鳕中都应该提到它,但资源消耗似乎在图书馆文档中经常被忽略。

于 2011-11-09T18:47:42.077 回答