[Haskell-cafe] saner shootout programs

Don Stewart dons at galois.com
Sun May 11 16:40:14 EDT 2008


jhc0033:
> I don't know Haskell very well, but even I can tell, looking at, for
> example, the N-body benchmark, that the Haskell code is probably not
> type-safe, and the tricks used in it would not be usable in a larger
> program (see below).
> 
> The task is essentially a pure computation: take a list of bodies
> having mass, position and velocity; apply Newton laws at discrete
> intervals for a large number of times; return new positions and
> velocities.
> 
> I could write a C++ procedure that performs this task and have some
> piece of mind regarding its type correctness, exception safety and
> functional purity: side effects would be local to the procedure,
> arguments passed as const or by value, the result returned by value,
> no type casts or new/delete operators used.
> 
> On the other hand, the Haskell code makes assumptions about the size
> of double-precision floats (obviously not type-safe). Further, the
> simulation is not a pure function.
> 
> It is often argued that one only needs these dirty tricks in the most
> time-consuming functions. However, if using imperative programming in
> these "inner loop" procedures places them in IO monad, the "outer
> loops" (the rest of the program - procedures that call it) will have
> to go there as well. This makes me doubt the Haskell approach to
> functional programming.
> 
> If anyone has a version of the N-body benchmark, where the simulation
> is a type-safe pure function, I would very much like to see and time
> it.

n-body requires updating a global array of double values to be
competitive performance-wise, though we haven't really nailed this
benchmark yet. The current entry should be considered an older approach
to raw performance -- typically we can get good (or better) results in
using the ST monad.

To improve safety, it should run in the ST monad. A version using ST is here,

    http://haskell.org/haskellwiki/Shootout/Nbody

However, the current fastest program should really be cross-ported to
run in ST, for best results. (Similar to the nsieve-bits program):

    http://shootout.alioth.debian.org/gp4/benchmark.php?test=nsievebits&lang=ghc&id=0

I suspect the optimisations that weren't happening, that
forced nbody to use Foreign.Ptr in the first place are likely obsolete
now -- GHC 6.8.2 should do a good job with STUArray Double, in careful
hands.

Also worth looking at is the other purely functional entry, in Clean,

    http://shootout.alioth.debian.org/gp4/benchmark.php?test=nbody&lang=clean&id=0

translation to Haskell should be fairly straightforward.

-- Don


More information about the Haskell-Cafe mailing list