[Haskell-cafe] Can't prevent memoizing in simple code

2012-05-16 Thread Yves Parès
The buffer http://hpaste.org/68595 presents a simple code I tried to
profile.
I spotted what I strongly think to be an abusive memoization. The problem
is that I don't see how to (simply) get rid of it.
Compiled with -O2, it consumes 130MB of memory, however lines A and B
executed separately consume each only 1MB.

The infinite list (l 1), whatever I do, keeps being shared between lines A
and B.
I tried to wrap it in a function, as you can see, I also tried to make it
explicitely polymorphic (bypassing monomorphic restriction), nothing solves
it, GHC is just to good at memoizing.

NB: When compiled without optimisations, the sharing does not happen (side
note: but then lack of strictness analysis -- which is what I was testing
at the first place -- makes line A (call to suminit2) consume a lot of
memory, but this is normal).
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Can't prevent memoizing in simple code

2012-05-16 Thread Anthony Cowley
On May 16, 2012, at 12:08 PM, Yves Parès wrote:

 The buffer http://hpaste.org/68595 presents a simple code I tried to profile.
 I spotted what I strongly think to be an abusive memoization. The problem is 
 that I don't see how to (simply) get rid of it.
 Compiled with -O2, it consumes 130MB of memory, however lines A and B 
 executed separately consume each only 1MB.
 
 The infinite list (l 1), whatever I do, keeps being shared between lines A 
 and B.
 I tried to wrap it in a function, as you can see, I also tried to make it 
 explicitely polymorphic (bypassing monomorphic restriction), nothing solves 
 it, GHC is just to good at memoizing.

Adding a {-# NOINLINE l #-} annotation helps here. Syntactically, it must be 
located somewhere a type signature for l would also be valid.

Anthony

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Can't prevent memoizing in simple code

2012-05-16 Thread Yves Parès
Thanks ^^

My other solution was a dirty trick:

Changing the second (l 1) by a (l (div 2 2)), which would only be good
until GHC knows how to statically analyse it (2-1 wasn't working for
instance).

I also noticed (while profiling to confirm that this was the source of the
memory leak) that adding manually cost centres forces the re-evaluation:

main = do
  print $ suminit2 ({-# SCC list1 #-} l 1) 100 0
  print $ fst $ suminit ({-# SCC list2 #-} l 1) 100 0
  where
l n = enumFrom n

CAF:main5  Main 97   00.00.026.6
50.0
  main  Main118   00.00.026.6
50.0
   list2Main119   00.00.026.6  *50.0
*
main.l  Main120   1   26.6   50.026.6
50.0
[...]
CAF:main8  Main 95   00.00.030.4
50.0
  main  Main110   00.00.030.4
50.0
   list1Main111   00.00.030.4
*50.0*
main.l  Main112   1   30.4   50.030.4
50.0

We see here that allocations are shared between list1 and list2 (I expected
list1 to get 100% and list2 0%, due to sharing).
Strange...

2012/5/16 Anthony Cowley acow...@gmail.com

 On May 16, 2012, at 12:08 PM, Yves Parès wrote:

 The buffer http://hpaste.org/68595 presents a simple code I tried to
 profile.
 I spotted what I strongly think to be an abusive memoization. The problem
 is that I don't see how to (simply) get rid of it.
 Compiled with -O2, it consumes 130MB of memory, however lines A and B
 executed separately consume each only 1MB.

 The infinite list (l 1), whatever I do, keeps being shared between lines A
 and B.
 I tried to wrap it in a function, as you can see, I also tried to make it
 explicitely polymorphic (bypassing monomorphic restriction), nothing solves
 it, GHC is just to good at memoizing.


 Adding a {-# NOINLINE l #-} annotation helps here. Syntactically, it must
 be located somewhere a type signature for l would also be valid.

 Anthony


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe