[Haskell-cafe] how to optmize this code?

Yves Parès limestrael at gmail.com
Thu Mar 31 14:27:59 CEST 2011


Just to be sure, because I am not quite familiar with the dark hairy
internals of GHC:

> Of course, given a type signature that allows strictness to be inferred.

You mean a signature with no type variables and types that are know to GHC
as being strict?
(Like Int -> Int -> Int instead of (Num a) => a -> a -> a)

> The difference is that the explicit recursion produces the better code
even
> with optimisations turned off, except that the overload of (+) to use is
> not inlined, so the accumulator still builds a thunk, while with
> optimisations you get the specialised strict additions (+# resp.
> plusInteger, ...) so you have the strictness you need.

(+#) is then the GHC's strict equivalent of (+)?
But if you make an overlay to (+), like, say:

(?) :: (Num a) => a -> a -> a
a ? b = a + b

Then (?) will be lazy, won't it?
Then optimizations will not occur, a ? b will remain a thunk and not be
replaced by a +# b and be strictly evaluated?

If so, then it means that you can always turn a strict function into a non
strict one, am I right?


2011/3/31 Daniel Fischer <daniel.is.fischer at googlemail.com>

> On Thursday 31 March 2011 11:45:00, Christian Maeder wrote:
> > Since we don't have a function sum' in the Prelude (should we have it?)
>
> I think we should.
>
> > I wonder what happens if you just use "sum". Will the "sum" (based on
> > sum' so without -DUSE_REPORT_PRELUDE) be strict enough?
>
> I don't know about other compiler's behaviour, but for GHC, it will be
> strict enough *if compiled with optimisations*, but not without (the
> strictness analyser runs only with optimisations turned on).
> - Of course, given a type signature that allows strictness to be inferred.
>
> However, the same holds for 'foldl (+) 0'. In fact, in the presence of a
> suitable type signature, with optimisations turned on, both produce nearly
> identical code (the order of parameters in the recursive loop is changed,
> sometimes parameter order can make a surprisingly large difference, but
> whether it's better to have the list or the accumulator first depends).
>
> The difference is that the explicit recursion produces the better code even
> with optimisations turned off, except that the overload of (+) to use is
> not inlined, so the accumulator still builds a thunk, while with
> optimisations you get the specialised strict additions (+# resp.
> plusInteger, ...) so you have the strictness you need.
>
> >
> > #ifdef USE_REPORT_PRELUDE
> > sum                     =  foldl (+) 0
> > product                 =  foldl (*) 1
> > #else
> > sum     l       = sum' l 0
> >    where
> >      sum' []     a = a
> >      sum' (x:xs) a = sum' xs (a+x)
> > product l       = prod l 1
> >    where
> >      prod []     a = a
> >      prod (x:xs) a = prod xs (a*x)
> > #endif
> >
> > Cheers C.
> >
> > P.S.
> >
> > isMultiple a = any ((== 0) . mod a)
>
> For Int (and most other types),
>
> isMultiples a = any ((== 0) . rem a)
>
> will be faster (mod is implemented using rem).
> However, for checks other than comparisons with 0, one needs to be aware of
> the differences of rem and mod, the latter does what one would expect, rem
> can badly surprise the unaware.
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20110331/5cb82e7d/attachment.htm>


More information about the Haskell-Cafe mailing list