Valerie94
Valerie94

Reputation: 303

Empty memory profile

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: enter image description here 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: enter image description here 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: enter image description here

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

Answers (1)

Reid Barton
Reid Barton

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

Related Questions