Merge pull request #33 from thomie/master
[packages/random.git] / tests / slowness.hs
1
2 -- http://hackage.haskell.org/trac/ghc/ticket/427
3
4 -- Two (performance) problems in one:
5
6 {-# OPTIONS -fffi #-}
7 module Main (main) where
8
9 import Control.Monad
10 import System.Random
11
12 foreign import ccall unsafe "random" _crandom :: IO Int
13 foreign import ccall unsafe "stdlib.hs" rand :: IO Int
14
15 randomInt :: (Int, Int) -> IO Int
16 randomInt (min,max) = do
17 -- n <- _crandom
18 n <- rand
19 return $ min + n `rem` range
20 where
21 range = max - min + 1
22
23 main = replicateM_ (5*10^6) $ do
24 x <- randomRIO (0::Int,1000) :: IO Int
25 -- x <- randomInt (0::Int,1000) :: IO Int
26 x `seq` return ()
27 return ()
28
29 -- First, without the "seq" at the end, hardly anything is
30 -- evaluated and we're building huge amounts of thunks.
31 -- Three ideas about this one:
32 -- - Blame the user :)
33 -- - data StdGen = StdGen !Int !Int
34 -- Use strict fields in StdGen. Doesn't actually help
35 -- (at least in this example).
36 -- - Force evaluation of the StdGen in getStdRandom.
37 -- Does help in this example, but also changes behaviour
38 -- of the library:
39 -- x <- randomRIO undefined
40 -- currently dies only when x (or the result of a later
41 -- randomRIO) is evaluated. This change causes it to die
42 -- immediately.
43
44 -- Second, even _with_ the "seq", replacing "randomRIO" by
45 -- "randomInt" speeds the thing up with a factor of about
46 -- 30. (2 to 3.6, in a "real world" university practicum
47 -- exercise of 900 lines of code)
48 -- Even given the fact that they're not really doing the
49 -- same thing, this seems rather much :(
50
51 --------------------------------------------------------------------------------
52
53 -- [2011.06.28] RRN:
54 -- I'm currently seeing 1425 ms vs 43 ms for the above. 33X
55 -- difference. If I use rand() instead it's about 52ms.