[Haskell-cafe] Re: Experiments with defunctionalization, church-encoding and CPS

Heinrich Apfelmus apfelmus at quantentunnel.de
Sun Nov 1 07:12:10 EST 2009


Eugene Kirpichov wrote:
> I took a toy problem - find the first node satisfying a predicate in a
> binary tree, started with a naive Maybe-based implementation - and
> experimented with 3 ways of changing the program:
>  - Church-encode the Maybe
>  - Convert the program into CPS
>  - Defunctionalize the Church-encoded or CPS-transformed program
> http://hpaste.org/fastcgi/hpaste.fcgi/view?id=10686
> 
> The link points to code, a benchmark and conclusion.
> 
> Conclusion:
>  - Haskell implements Maybe well enough that it is not possible to do better
>  - Defunctionalization and consequent optimization yields same
> performance as the one with Maybe
>  - Non-simplified CPS and Church-encoded representations do bad

I'm not sure your example program is enough to justify the conclusions.


The main advantage of the Church-encoding of  Maybe

    type Maybe' a = forall b . b -> (a -> b) -> b

is that the latter has the pattern match for failure / success built-in
when used as a monad

    m >>= g  = \nothing just -> m nothing (\x -> g x nothing just)

  VS

    m >>= g  = case m of
        Nothing -> Nothing
        Just x  -> g x

The algebraic data type has to check that the result was indeed  Just x
 whereas the Church-encoding can jump right to the success continuation.


The problem is that your tree doesn't really make use of this advantage.
For that, you need a completely left-biased tree, like for example

    Fork 1 (Fork 2 (Fork 3 ... Leaf) Leaf) Leaf

    testTree = fromList [1..100000]
    fromList = foldr (\x t -> Fork x t Leaf) Leaf

I've implemented this and posted it below your version at

    http://hpaste.org/fastcgi/hpaste.fcgi/view?id=10686

I've used the  criterion  benchmarking package, so you can run this
straight out of the box.


Even then, the results are mixed. The Church-encoding shines in GHCi as
it should, but loses its advantage when the code is being compiled. I
guess we have to look at the core if we want to know what exactly is
going on.


PS: I'm not entirely sure I'm using  criterion  correctly, in particular
 concerning strictness. For instance, dropping the  fromJust  will
reduce the run-time of the "data Maybe" benchmark by 75%. Comments?


Regards,
apfelmus

--
http://apfelmus.nfshost.com



More information about the Haskell-Cafe mailing list