2017-02-20 100 views
2

我想測試一個小測試程序的內存使用情況。該程序如下所示:空內存​​配置文件

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

它找到了第100000個值。我期望看到這個程序只會使用內存100000個值。當我通過+RTS -hy生成內存配置文件時,我得到一個空的配置文件: enter image description here 我很驚訝,並認爲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 

儘管如此,存儲配置文件是空的。我認爲這是因爲GHC在這個程序上執行某種融合,其中值由takeUntil計算並同時打印,因此可以立即進行垃圾收集。

所以我寫了一個需要從takeUntil結果留在內存其他程序:

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

這使存儲的個人資料,我期待: enter image description here 我想看看該程序將使用什麼內存,如果我只請求了一半的樣本:

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 

存儲的個人資料是我所期望的: enter image description here

有人能解釋這種現象?

該代碼位於名爲Main.hs的文件中。我通過ghc Main.hs -O2 -rtsopts -prof編譯。我通過運行+RTS -hy來構建內存配置文件,並使用hp2ps -e8in -cps2pdf生成pdf。

+3

默認堆配置文件頻率爲每0.1秒,所以也許你的空配置文件只是因爲程序運行不夠長。您可以使用'-i 'RTS選項調整堆配置文件頻率。 –

+0

@ReidBarton謝謝,就是這樣! – Valerie94

+0

@ReidBarton這應該是一個答案。 – jkeuhlen

回答

3

默認的堆配置文件頻率是每0.1秒,所以如果你的程序運行不夠長,那麼你會得到一個空的堆配置文件。您可以使用-i<sec> RTS選項調整堆配置文件頻率。