[Haskell-cafe] Performance with do notation, mwc-random and unboxed vector

Roman Leshchinskiy rl at cse.unsw.edu.au
Mon Jun 11 23:08:35 CEST 2012


On 11/06/2012, at 10:38, Dmitry Dzhus wrote:

> Consider this simple source where we generate an unboxed vector with million
> pseudo-random numbers:
> 
> ---- 8< -----
> import qualified Data.Vector.Unboxed as VU
> 
> import System.Random.MWC
> import System.Random.MWC.Distributions (standard)
> 
> count = 1000000
> 
> main = do
>  g <- create
>  e' <- VU.replicateM count $ standard g
>  return ()
> ---- >8 -----
> 
> Being compiled with -O2, this runs for 0.052 s on my machine.
> 
> Changing the replicateM line to use do notation brings the runtime down to 11.257 s!
> See below:
> 
> ---- 8< -----
> import qualified Data.Vector.Unboxed as VU
> 
> import System.Random.MWC
> import System.Random.MWC.Distributions (standard)
> 
> count = 1000000
> 
> main = do
>  g <- create
>  e' <- VU.replicateM count $ do
>           v <- standard g
>           return v
>  return ()
> ---- >8 -----

The former essentially generates this:

  replicateM n ((letrec f = ... in f) `cast` ...)

and the latter this:

  replicateM n (\(s :: State# RealWorld) -> (letrec f = ... in f s) `cast` ...)

I'd look further into this but mwc-random just inlines too much stuff. Could you perhaps find a smaller example that doesn't use mwc-random? In any case, it looks like a GHC bug, perhaps the state hack is getting in the way.

Roman





More information about the Haskell-Cafe mailing list