Haskell 内存分析更改内存使用情况(为了更好)

Haskell 内存分析更改内存使用情况(为了更好),haskell,memory-profiling,Haskell,Memory Profiling,这实际上是一个问题的后续问题。 我设法让评测工作起来,问题似乎真的是懒惰的评估 我使用的数据结构是一个Map Int(Map Int Text),其中Text来自。问题是,构建这张地图的函数会产生巨大的震动。处理大约3MB的输入文本时,程序需要超过250MB的内存 现在谈谈这个问题的真正目的: 要获取此数据结构中的字符数,请使用以下函数: type TextResource = M.Map Int (M.Map Int T.Text) totalSize :: TextResouce ->

这实际上是一个问题的后续问题。 我设法让评测工作起来,问题似乎真的是懒惰的评估

我使用的数据结构是一个
Map Int(Map Int Text)
,其中
Text
来自。问题是,构建这张地图的函数会产生巨大的震动。处理大约3MB的输入文本时,程序需要超过250MB的内存

现在谈谈这个问题的真正目的:

要获取此数据结构中的字符数,请使用以下函数:

type TextResource = M.Map Int (M.Map Int T.Text)

totalSize :: TextResouce -> Int
totalSize = M.fold ((+) . (M.fold ((+). T.length) 0)) 0
不漂亮,但它完成了任务。在创建TextResource之后,我正在主函数中使用此函数。有趣的是,当我使用RTS选项
-hr
-hc
评测程序时,内存使用量会在一段时间后下降到70或50 MB,这完全可以

不幸的是,这只在使用评测选项和
totalSize
函数时起作用-如果没有它们,则返回到250 MB

我上传了程序(<70行)以及一个测试文件和一个阴谋文件,这样你就可以自己尝试了:

xml是一个生成的xml文件,应该放在executables目录中。 要进行构建,
cabalconfigure——启用可执行评测
,然后
cabalbuild
就足够了(如果您安装了所需库的评测版本)

使用
+RTS-hc
运行程序一次和不运行程序一次时,可以看到更改

如果有人能运行这个程序,我会非常高兴,因为我真的被困在这里了。我已经尝试在多个地方输入了
deepseq
,但是没有任何效果(除了使用评测选项之外)

编辑:

然而,分析确实表明,只使用了约20MB的堆,因此在我的评论中,我指责GHC没有释放您想要的GC托儿所内存

谢谢,这为我指明了正确的方向。事实证明,在对映射进行深度排序之后,您可以告诉GHC执行一个垃圾收集(),它工作得非常好。尽管我猜不推荐使用performGC,但它似乎是适合这项工作的工具

Edit2: 这就是我如何更改主函数(+返回buildTextFile):

main=do-tf
问题是,构建这张地图的函数会产生巨大的震动

不。基于堆分析,我不认为空间使用是thunks。此外,我还用严格的HashMaps替换了
Data.Map
,并强制使用相同的结果生成映射(以避免创建大型thunk)

当我使用RTS选项-hr或-hc评测程序时,一段时间后内存使用量下降到70或50 MB

我不能复制这个。使用
-hr
-hy
-hc
时,进程将保留140MB的堆。然而,分析确实表明,只使用了约20MB的堆,因此在我的评论中,我指责GHC没有释放您想要的GC托儿所内存


至于计算期间的高内存使用,上面的
-hy
配置文件显示大部分内存是由于
字符串类型和HaXML库
Posn
类型造成的。我将重申我的建议,即寻找一个基于
ByteString
Text
的XML库,该库的资源更加简洁(XML枚举器?)

我实际上并不关心构建映射时的内存使用情况。但在构建之后,内存使用应该会下降,就像我使用评测时一样。这是困扰我的,这是我不明白的。啊,我明白了。我还是不认为你对thunks有意见。用严格的hashmaps替换映射(并强制它们)不会改善wrt内存使用。注意:使用完全重写进行编辑。编辑了我的帖子并接受了你的答案,因为它向我指出了解决方案:performGC。谢谢你的帮助!嗯,我以为我已经测试过了,但它似乎对我没有帮助。很高兴它对你有用!还有写得很好的问题,顺便说一句,包括可运行的测试用例和一切——非常好。
main = do tf <- buildTextFile "test.xml"
          performGC
          putStrLn . show . text 1 1000 $ tf
          getLine
          putStrLn . show . text 100 1000 $ tf
          return ()