【问题标题】:Empty memory profile空内存配置文件
【发布时间】:2017-02-20 17:30:10
【问题描述】:

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

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 选项调整堆配置文件频率。
  • @ReidBarton 谢谢,就是这样!
  • @ReidBarton 这应该是一个答案。

标签: haskell lazy-evaluation heap-memory


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-26
    • 2012-04-23
    • 2014-10-24
    • 2019-07-10
    • 2021-06-21
    相关资源
    最近更新 更多