Space leak

Christian Maeder maeder at tzi.de
Wed Dec 28 12:41:35 EST 2005


Tomasz Zielonka wrote:
> On Tue, Dec 27, 2005 at 08:12:20PM +0100, Christian Maeder wrote:
>> Already the following bit exhibits unexpected memory consumption:
>>
>> main = mapM_ print $ take (n * 5) $ drop (n * 3) [1..]
>> n = 100000
> 
> I think it's the (succ (succ (succ ...))) thunk. When you change it to
> [1..99999999] there is no space leak - here every produced element must
> be examined before producing the next list node or [].

ok, I could also fix the space leak by defining my own iterate function:

myiterate :: (a -> a) -> a -> [a]
myiterate f a = a : (myiter f $! f a)

main =
    mapM_ print $ take (n * 5) $ drop (n * 3) $ myiterate succ 1

is also ok.

The next problem occurs when I try to use splitAt as in the original DNA 
example:

main = do
   let (s1, s2) = splitAt (n * 3) $ myiterate succ 1
   mapM_ print s1
   mapM_ print $ take (n * 5) s2

The above code leaks space! But

main = do
   let s1 = take (n * 3) $ myiterate succ 1
       s2 = drop (n * 3) $ myiterate succ 1
   mapM_ print s1
   mapM_ print $ take (n * 5) s2

does not leak, as long as it is compiled without optimization.
(Eliminating the CSE "myiterate succ 1" makes it leak.)

Could optimization be improved?

Cheers Christian



More information about the Glasgow-haskell-bugs mailing list