[Haskell-cafe] Re: Profiling nested case

Ryan Ingram ryani.spam at gmail.com
Mon Jul 21 03:36:44 EDT 2008


I had similar experiences as you when attempting to write "high
performance Haskell"; the language makes you want to use high-level
abstracted functions but the optimizer (while amazing, to be honest)
seems to miss a few cases that it seems like it should hit.

The problem seems to be that the compiler is extremely good at
optimizing systems-level code, but that any "control-structure"
function needs to be extremely inlined to be successful.  You might
try re-writing "sequence" or "foldM" a few different ways using the
same "test" function and see what you can get.

One thing that I notice about this code is that if you switch Right
and Left you will get the default behavior for the Either monad:

worldSceneSwitch point = case redSphere (0,50,0) 50 point of
   v@(Left _) -> v
   Right d1 -> case greenSphere (25,-250,0) 50 point of
     v@(Left _) -> v
     Right d2 -> Right $ d1 `min` d2

is the same as

worldSceneSwitch point = do
    d1 <- redSphere (0, 50, 0) 50 point
    d2 <- greenSphere (25, -250, 0) 50 point
    Right (d1 `min` d2)

Here is the same concept using foldM:

minimumM (x : xs) = do
    v0 <- x
    foldM (return . min) v0 xs

worldSceneSwitch point = minimumM [
    redSphere (0, 50, 0) 50 point,
    greenSphere (25, -250, 0) 50 point
  ]

However, the performance here will be terrible if minimumM and foldM
do not get sufficiently inlined; you do not want to be allocating list
thunks just to execute them shortly thereafter.

  -- ryan

On Sat, Jul 19, 2008 at 6:48 AM, Mitar <mmitar at gmail.com> wrote:
> Hi!
>
> I had to change code somewhat. Now I have a function like:
>
> worldScene point = case redSphere (0,50,0) 50 point of
>  v@(Right _) -> v
>  Left d1 -> case greenSphere (25,-250,0) 50 point of
>    v@(Right _) -> v
>    Left d2 -> Left $ d1 `min` d2
>
> (Of course there could be more objects.)
>
> Any suggestion how could I make this less hard-coded? Something which
> would take a list of objects (object functions) and then return a
> Right if any object function return Right or a minimum value of all
> Lefts. But that it would have similar performance? If not on my GHC
> version (6.8.3) on something newer (which uses fusion or something).
> Is there some standard function for this or should I write my own
> recursive function to run over a list of object functions? But I am
> afraid that this will be hard to optimize for compiler.
>
> (It is important to notice that the order of executing object
> functions is not important so it could be a good candidate for
> parallelism.)
>
>
> Mitar
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>


More information about the Haskell-Cafe mailing list