Reputation: 303
I wanted to test the memory usage of a small test program. The program looks as follows:
import Data.List as L
main :: IO
main = print $ L.find (==100000) [1..1000000000]
It finds the 100000th value. I expected to see that this program would only use the memory for 100000 values. When I generated a memory profile via +RTS -hy
I got an empty profile:
I was surprised and thought that
GHC
may be more efficient than I thought. Maybe the values never had to be loaded into memory since the result can already be determined.
So I experimented with a problem that requires all the values up until the 100000th:
main = print $ takeUntil (==100000) [1..]
takeUntil :: (Int -> Bool) -> [Int] -> [Int]
takeUntil _ [] = []
takeUntil f (x:xs) = if f x
then []
else x : takeUntil f xs
Still, the memory profile is empty. I thought this was because GHC is performing some kind of fusion on this program in which values are calculated by takeUntil
and printed at the same time so they can be instantly garbage collected.
So I wrote another program that requires the result from takeUntil
to stay in memory:
main = let taken = takeUntil (==100000) [1..]
mapped = L.map (+1) taken
in print taken >> print mapped
This gives the memory profile I was expecting:
I wanted to see what memory the program would use if I requested only half of the samples:
main = let taken = takeUntil (==50000) [1..]
mapped = L.map (+1) taken
in print taken >> print mapped
I generated the memory profile and yet again it's empty!
When I request more samples:
main = let taken = takeUntil (==200000) [1..]
mapped = L.map (+1) taken
in print taken >> print mapped
The memory profile is as I would expect:
Can someone explain this behavior?
The code is in a file called Main.hs
. I compile via ghc Main.hs -O2 -rtsopts -prof
. I build the memory profile by running with +RTS -hy
and generate a pdf using hp2ps -e8in -c
and ps2pdf
.
Upvotes: 2
Views: 220
Reputation: 15019
The default heap profile frequency is every 0.1 s, so if your program doesn't run for long enough then you'll get an empty heap profile. You can adjust the heap profile frequency with the -i<sec>
RTS option.
Upvotes: 4