Q: Forcing repeated evaluation

Adrian Hey ahey@iee.org
Thu, 12 Sep 2002 12:14:42 +0100


On Thursday 12 September 2002 10:43 am, Martin Norbäck wrote:
> tor 2002-09-12 klockan 11.27 skrev Jan Kybic:
> > Hello,
> >         I have another question regarding the optimisation of Haskell
> > code: I have a relatively inexpensive function generating a long list,
> > imagine something like (I simplified a lot):
> >
> > l = [ i*i*i | i <- [0..n] ]   -- for very large n
> >
> > This long list is consumed several times in the program:
> >
> > x1 = f1 l
> > x2 = f2 x1 l
> > x3 = f3 x2 l
> >
> > I found that the list l is calculated just once and that the
> > computational time is dominated by the allocations and garbage
> > collection. I want to try to force l to be generated on-the-fly
> > every time it is needed, to see if it improves performance.
> > What is a good way to do it? Would something like
> >
> > unsafePerformIO $ return l
> >
> > do the job? Isn'it there any flag for the compiler (ghc) to suggest
> > this optimisation? Thank you for your feedback.
>
> The easiest way is to make it a function
>
> l _ = [ i*i*i | i <- [0..n] ]   -- for very large n
>
> x1 = f1 (l ())
> x2 = f2 x1 (l ())
> x3 = f3 x2 (l ())

I asked a similar question a while ago, and (I think) there was general
agreement that this was not a reliable solution because the expression
(l ()) is still a CAF and there's nothing to stop a Haskell implementation
"optimising" occurrences of this expression to a single shared heap object
(and creating a space leak potentially). I think whether or not this works
reliably depends on compiler implementation and/or chosen optimisation level.

I understand that Clean addresses this problem by defining the language
semantics in terms of graph re-writing rather than lambda calculus. So,
I guess Clean outlaws transformations which change the sharing of graphs.

It seems a pity something similar can't be done for Haskell. For GHC
I was told the -fno-full-laziness flag (or something like that) will
stop the sharing, but the GHC doc's make no mention of this flag as far
as I can see :-(

Regards
--
Adrian Hey