我想测试一个小测试程序的内存使用情况。该计划如下:
ALTER TABLE sys_cart
MODIFY COLUMN userid INT PRIMARY KEY
找到第100000个值。我希望看到这个程序只能使用100000个值的内存。当我通过import Data.List as L
main :: IO
main = print $ L.find (==100000) [1..1000000000]
生成内存配置文件时,我得到一个空配置文件:
我很惊讶并认为+RTS -hy
可能比我想象的更有效率。也许这些值永远不会被加载到内存中,因为结果已经可以确定了。
所以我尝试了一个需要所有值直到100000的问题:
GHC
仍然,内存配置文件为空。我认为这是因为GHC正在对这个程序进行某种融合,其中值由main = print $ takeUntil (==100000) [1..]
takeUntil :: (Int -> Bool) -> [Int] -> [Int]
takeUntil _ [] = []
takeUntil f (x:xs) = if f x
then []
else x : takeUntil f xs
计算并同时打印,因此可以立即进行垃圾收集。
所以我编写了另一个程序,要求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 -c
生成pdf。
答案 0 :(得分:3)
默认的堆配置文件频率是每0.1秒,所以如果你的程序没有运行足够长的时间,那么你将得到一个空的堆配置文件。您可以使用-i<sec>
RTS选项调整堆配置文件频率。