[Haskell-cafe] Using Product Algebraic types
David Menendez
zednenem at psualum.com
Sun Jul 4 18:38:34 EDT 2004
Sven Panne writes:
> David Menendez wrote:
> > [...] If that turned out to be a performance bottleneck, you could
> > factor out pair and write f directly: [...]
>
> .... or directly complain to your compiler supplier if the compiler
> in question does not do this simple transformation for you. :-)
Sure. It's a longer-term strategy, though. :-)
> Let's e.g. have a look at the code generated by GHC for the
> "inefficient" version:
Neat! Are you getting this from -ddump-simpl?
> ---------------------------------------------------------------------
> helper :: (Fitness, a) -> (Fitness, a) -> (Fitness, a)
> helper = \ds eta ->
> case ds of
> (f, a) -> case eta of
> (g, b) -> (g `plusInteger` f, b)
>
> rw :: Population a -> Population a
> rw = \ds ->
> case ds of
> Population xs ->
> Population (case xs of
> (x:xs1) -> scanl helper x xs1
> [] -> [])
> ----------------------------------------------------------------------
<snip>
> What has happened? `pair', `id', and `scanl1' were completely inlined
> and instead of the overloaded (+), an Integer-specific addition was
> chosen (`plusInteger', it's not the real name, just something for
> presentation purposes). Although these are all only O(1)
> optimizations (nothing "really clever"), one can hardly do better by
> hand... So keep the program in a form which is most comprehensible,
> even if this seems to imply some "superfluous" things at first. This
> enables you to have more time for more interesting things which could
> really have some effect on performance, like clever algorithms etc.
I completely agree.
Actually, I might have suggested using (***) or first from Control.Arrow
rather than defining pair, since they effectively do the same thing. But
looking at the Core output I see that:
rw2 :: Population a -> Population a
rw2 (Population xs) = Population (scanl1 f xs)
where
f (n,a) = (+n) *** id
yields (if I'm interpreting it right):
helper2 = \ds eta ->
case ds of
(n,a) -> ( case eta of
(x,y) -> x `plusInt` y
, case eta of
(x,y) -> y
)
rw2 = \ds ->
case ds of
Population xs ->
Population (case xs of
(x:xs1) -> scanl helper2 x xs1
[] -> []
)
I don't know what to make of that. Semantically, helper2 is identical to
helper, but I'm not brave enough to look at the C output to see if they
produce different results.
--
David Menendez <zednenem at psualum.com> | "In this house, we obey the laws
<http://www.eyrie.org/~zednenem> | of thermodynamics!"
More information about the Haskell-Cafe
mailing list