File: Bench.hs

package info (click to toggle)
haskell-splitmix 0.1.0.5-2
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 196 kB
  • sloc: haskell: 1,366; ansic: 151; sh: 53; makefile: 9
file content (152 lines) | stat: -rw-r--r-- 5,343 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
module Main (main) where

import Criterion.Main
import Data.List (unfoldr)
import Data.Word (Word64)

import qualified Data.Tree as T
import qualified System.Random as R
import qualified System.Random.TF as TF
import qualified System.Random.TF.Instances as TF
import qualified System.Random.SplitMix as SM
import qualified System.Random.SplitMix32 as SM32

-------------------------------------------------------------------------------
-- List
-------------------------------------------------------------------------------

-- infinite list
genList :: (g -> (Int, g)) -> g -> [Int]
genList next = unfoldr (Just . next)

-- truncated
genListN :: (g -> (Int, g)) -> g -> [Int]
genListN next = take 2048 . genList next

randomList :: Int -> [Int]
randomList = genListN R.random . R.mkStdGen

tfRandomList :: Word64 -> [Int]
tfRandomList w64 = genListN R.random $ TF.seedTFGen (w64, w64, w64, w64)

splitMixList :: Word64 -> [Int]
splitMixList w64 = genListN SM.nextInt $ SM.mkSMGen w64

splitMix32List :: Word64 -> [Int]
splitMix32List w64 = genListN SM32.nextInt $ SM32.mkSMGen $ fromIntegral w64

-------------------------------------------------------------------------------
-- Tree
-------------------------------------------------------------------------------

genTree :: (g -> (Int, g)) -> (g -> (g, g)) -> g -> T.Tree Int
genTree next split = go where
    go g = case next g of
        ~(i, g') -> T.Node i $ case split g' of
            (ga, gb) -> [go ga, go gb]

genTreeN :: (g -> (Int, g)) -> (g -> (g, g)) -> g -> T.Tree Int
genTreeN next split = cutTree 9 . genTree next split
  where
    cutTree :: Int -> T.Tree a -> T.Tree a
    cutTree n (T.Node x forest)
        | n <= 0    = T.Node x []
        | otherwise = T.Node x (map (cutTree (n - 1)) forest)

randomTree :: Int -> T.Tree Int
randomTree = genTreeN R.next R.split . R.mkStdGen

tfRandomTree :: Word64 -> T.Tree Int
tfRandomTree w64 = genTreeN R.next R.split $ TF.seedTFGen (w64, w64, w64, w64)

splitMixTree :: Word64 -> T.Tree Int
splitMixTree w64 = genTreeN SM.nextInt SM.splitSMGen $ SM.mkSMGen w64

splitMix32Tree :: Word64 -> T.Tree Int
splitMix32Tree w64 = genTreeN SM32.nextInt SM32.splitSMGen $ SM32.mkSMGen $ fromIntegral w64

-------------------------------------------------------------------------------
-- List Word64
-------------------------------------------------------------------------------

-- infinite list
genList64 :: (g -> (Word64, g)) -> g -> [Word64]
genList64 r = unfoldr (Just . r)

-- truncated
genListN64 :: (g -> (Word64, g)) -> g -> [Word64]
genListN64 r = take 2048 . genList64 r

randomList64 :: Int -> [Word64]
randomList64 = genListN64 R.random . R.mkStdGen

tfRandomList64 :: Word64 -> [Word64]
tfRandomList64 w64 = genListN64 TF.random $ TF.seedTFGen (w64, w64, w64, w64)

splitMixList64 :: Word64 -> [Word64]
splitMixList64 w64 = genListN64 SM.nextWord64 $ SM.mkSMGen w64

splitMix32List64 :: Word64 -> [Word64]
splitMix32List64 w64 = genListN64 SM32.nextWord64 $ SM32.mkSMGen $ fromIntegral w64

-------------------------------------------------------------------------------
-- Tree Word64
-------------------------------------------------------------------------------

genTree64 ::(g -> (Word64, g)) -> (g -> (g, g)) -> g -> T.Tree Word64
genTree64 r split = go where
    go g = case r g of
        ~(i, g') -> T.Node i $ case split g' of
            (ga, gb) -> [go ga, go gb]

genTreeN64 :: (g -> (Word64, g)) -> (g -> (g, g)) -> g -> T.Tree Word64
genTreeN64 r split = cutTree 9 . genTree64 r split
  where
    cutTree :: Word64 -> T.Tree a -> T.Tree a
    cutTree n (T.Node x forest)
        | n <= 0    = T.Node x []
        | otherwise = T.Node x (map (cutTree (n - 1)) forest)

randomTree64 :: Int -> T.Tree Word64
randomTree64 = genTreeN64 R.random R.split . R.mkStdGen

tfRandomTree64 :: Word64 -> T.Tree Word64
tfRandomTree64 w64 = genTreeN64 TF.random R.split $ TF.seedTFGen (w64, w64, w64, w64)

splitMixTree64 :: Word64 -> T.Tree Word64
splitMixTree64 w64 = genTreeN64 SM.nextWord64 SM.splitSMGen $ SM.mkSMGen w64

splitMix32Tree64 :: Word64 -> T.Tree Word64
splitMix32Tree64 w64 = genTreeN64 SM32.nextWord64 SM32.splitSMGen $ SM32.mkSMGen $ fromIntegral w64

-------------------------------------------------------------------------------
-- Main
-------------------------------------------------------------------------------

main :: IO ()
main = defaultMain
    [ bgroup "list"
        [ bench "random"     $ nf randomList 42
        , bench "tf-random"  $ nf tfRandomList 42
        , bench "splitmix"   $ nf splitMixList 42
        , bench "splitmix32" $ nf splitMix32List 42
        ]
    , bgroup "tree"
        [ bench "random"     $ nf randomTree 42
        , bench "tf-random"  $ nf tfRandomTree 42
        , bench "splitmix"   $ nf splitMixTree 42
        , bench "splitmix32" $ nf splitMix32Tree 42
        ]
    , bgroup "list 64"
        [ bench "random"     $ nf randomList64 42
        , bench "tf-random"  $ nf tfRandomList64 42
        , bench "splitmix"   $ nf splitMixList64 42
        , bench "splitmix32" $ nf splitMix32List64 42
        ]
    , bgroup "tree 64"
        [ bench "random"     $ nf randomTree64 42
        , bench "tf-random"  $ nf tfRandomTree64 42
        , bench "splitmix"   $ nf splitMixTree64 42
        , bench "splitmix32" $ nf splitMix32Tree64 42
        ]
    ]