[Haskell-cafe] how to optmize this code?
daniel.is.fischer at googlemail.com
Thu Mar 31 12:18:46 CEST 2011
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
> sum l = sum' l 0
> sum'  a = a
> sum' (x:xs) a = sum' xs (a+x)
> product l = prod l 1
> prod  a = a
> prod (x:xs) a = prod xs (a*x)
> Cheers C.
> 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.
More information about the Haskell-Cafe