清空内存配置文件

Empty memory profile

我想测试一个小测试程序的内存使用情况。该程序如下所示:

import Data.List as L
main :: IO
main = print $ L.find (==100000) [1..1000000000]

它找到第 100000 个值。我希望看到这个程序只会将内存用于 100000 个值。当我通过 +RTS -hy 生成内存配置文件时,我得到了一个空配置文件: 我很惊讶,认为 GHC 可能比我想象的更有效率。也许这些值永远不必加载到内存中,因为结果已经可以确定了。

所以我尝试了一个问题,它需要直到第 100000 个值的所有值:

main = print $ takeUntil (==100000) [1..]

takeUntil :: (Int -> Bool) -> [Int] -> [Int]
takeUntil _ [] = []
takeUntil f (x:xs) = if f x
                      then []
                      else x : takeUntil f xs

内存配置文件仍然是空的。我认为这是因为 GHC 正在对该程序执行某种融合,其中值由 takeUntil 计算并同时打印,因此它们可以立即被垃圾收集。

所以我编写了另一个程序,需要 takeUntil 的结果保留在内存中:

main = let taken = takeUntil (==100000) [1..]
           mapped = L.map (+1) taken
       in print taken >> print mapped

这给出了我期望的内存配置文件: 我想看看如果我只请求一半的样本,程序会使用多少内存:

main = let taken = takeUntil (==50000) [1..]
           mapped = L.map (+1) taken
       in print taken >> print mapped

我生成了内存配置文件,但它还是空的!

当我请求更多样本时:

main = let taken = takeUntil (==200000) [1..]
           mapped = L.map (+1) taken
       in print taken >> print mapped

内存配置文件如我所料:

有人可以解释这种行为吗?

代码位于名为 Main.hs 的文件中。我通过 ghc Main.hs -O2 -rtsopts -prof 编译。我通过 运行 +RTS -hy 构建内存配置文件并使用 hp2ps -e8in -cps2pdf.

生成 pdf

默认的堆配置文件频率是每 0.1 秒一次,因此如果您的程序没有 运行 足够长的时间,那么您将得到一个空的堆配置文件。您可以使用 -i<sec> RTS 选项调整堆分析频率。