ppad-random-0.1.0: bench/Weight.hs
{-# LANGUAGE BangPatterns #-}
module Main where
import qualified Crypto.CSPRNG as CSPRNG
import qualified Crypto.PRNG as PRNG
import qualified Crypto.PRNG.Pure as Pure
import qualified Data.ByteString as BS
import Data.Word (Word64)
import Weigh
-- note that 'weigh' doesn't work properly in a repl
main :: IO ()
main = do
prng <- PRNG.new 42
let !pg = Pure.new 42
mc <- CSPRNG.new (BS.replicate 32 0)
case mc of
Nothing -> error "ppad-random (weigh): invalid seed"
Just csprng -> mainWith $ do
wgroup "PRNG" $ do
io "word64 (x1000)" (sum_words (PRNG.word64 prng)) 1000
io "double (x1000)" (sum_doubles (PRNG.double prng)) 1000
wgroup "PRNG.Pure" $ do
func "word64 (x1000)" (sum_draws Pure.word64 pg) 1000
func "double (x1000)" (sum_draws Pure.double pg) 1000
func "int_range 1 6 (x1000)" (sum_draws (Pure.int_range 1 6) pg) 1000
wgroup "CSPRNG" $ do
io "word64 (x1000)" (sum_words (CSPRNG.word64 csprng)) 1000
io "bytes (32B)" (\n -> CSPRNG.bytes n csprng) 32
io "bytes (1024B)" (\n -> CSPRNG.bytes n csprng) 1024
sum_words :: IO Word64 -> Int -> IO Word64
sum_words gen = loop 0 where
loop !acc n
| n <= 0 = pure acc
| otherwise = do
!w <- gen
loop (acc + w) (n - 1)
{-# INLINE sum_words #-}
sum_doubles :: IO Double -> Int -> IO Double
sum_doubles gen = loop 0 where
loop !acc n
| n <= 0 = pure acc
| otherwise = do
!d <- gen
loop (acc + d) (n - 1)
{-# INLINE sum_doubles #-}
-- sum the results of n draws from a pure generator
sum_draws :: Num a => (Pure.Gen -> Pure.Draw a) -> Pure.Gen -> Int -> a
sum_draws f = loop 0 where
loop !acc !g n
| n <= 0 = acc
| otherwise = case f g of
Pure.Draw x ng -> loop (acc + x) ng (n - 1)
{-# INLINE sum_draws #-}