Performance: Faster to define a function writing out all arguments?

Alexander Fuchs alexander.fuchs at
Wed May 14 12:58:11 EDT 2008


Simon Peyton-Jones wrote:
> | I've definitely run into the odd other case where point-freeing
> | a bit of code messes with the complexity.
> That should not happen -- except for the state-hack. Which is this:
> Consider
>         f1 :: Char -> IO ()
>         f1 = \c. let i = ord c in \s. print i s
> Here s::State World.  Is this equivalent to
>         f2 = \c.\s. print (ord c) s
> The latter is very much more efficient than 'f1', because it doesn't build an intermediate lambda.  This matters a lot in I/O-intensive programs.   But if 'f' is called thus:
>         forever (f 'w')
> then (ord 'w') is computed once for each call of f2, but is shared among all calls to f1.  And that can make a big difference too.

Thanks for the explanation. State World here really means the IO and ST 
monad, not the State monad, right?

Compiling with -fno-state-hack actually does actually lead to both 
versions (the point-free and explicit) being equally fast (14.4s instead 
of 15.2s resp. 14.0s). Though I am not sure why. Running in profiled 
mode makes all difference vanish.

I tested this on an Intel(R) Pentium(R) 4 CPU 3.00GHz and got the 
reported speed difference there. Using instead an AMD Athlon(tm) 64 
Processor 3800+ I got no difference even without using -fno-state-hack.

> I have no idea whether this is playing a role in the example you are discussing -- my guess is not, and there may be another performance bug lurking. So eliciting a small demo would be great.

I am sorry, I completely failed to do that. The parser builds up a data 
structure from several data types using memoization. Any significant 
simplification of the code base reduced the performance gap until it 
quickly disappeared.


More information about the Glasgow-haskell-users mailing list