Skip to content

Commit 4048469

Browse files
committed
Fourth implementation, remove next alloc
❯ time .stack-work/install/x86_64-osx/lts-13.21/8.6.5/bin/bingo-sim 100000 Trials: 100000 Bingos: 3670 Hit rate: 0.0367 0.08s user 0.01s system 86% cpu 0.101 total
1 parent 0a04839 commit 4048469

File tree

5 files changed

+117
-18
lines changed

5 files changed

+117
-18
lines changed

bingo-sim.cabal

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ cabal-version: 1.12
44
--
55
-- see: https://github.com/sol/hpack
66
--
7-
-- hash: 3fa6868be54f56e844ce88095718d2f5be4a44d809a636babdeadda66d9faeba
7+
-- hash: 722efc688c7d34bdbe0a8a50324f74bfab1fc251f16b7f108844ae6a3f28e9ab
88

99
name: bingo-sim
10-
version: 0.0.3.0
10+
version: 0.0.4.0
1111
synopsis: A small playground to learn about profiling Haskell.
1212

1313
description: This package simulates the probability of scoring a bingo at a particular children's carnival game. I've been using it to learn how profiling in Haskell works.

package.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: bingo-sim
2-
version: 0.0.3.0
2+
version: 0.0.4.0
33
homepage: https://github.com/jez/bingo-sim
44
author: Jake Zimmerman
55
maintainer: zimmerman.jake@gmail.com

prof/bingo-sim.4.prof

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
Mon May 20 01:37 2019 Time and Allocation Profiling Report (Final)
2+
3+
bingo-sim +RTS -p -RTS 100000
4+
5+
total time = 0.43 secs (431 ticks @ 1000 us, 1 processor)
6+
total alloc = 808,788,160 bytes (excludes profiling overheads)
7+
8+
COST CENTRE MODULE SRC %time %alloc
9+
10+
next BingoSim.Prng src/BingoSim/Prng.hs:(79,1)-(91,40) 50.6 48.5
11+
shuffleBits.withRand BingoSim.Simulation src/BingoSim/Simulation.hs:(125,3)-(128,39) 16.5 31.2
12+
shuffleBits.withRand.bs' BingoSim.Simulation src/BingoSim/Simulation.hs:127:9-45 13.7 6.9
13+
swapBits BingoSim.Simulation src/BingoSim/Simulation.hs:(140,1)-(143,46) 10.0 6.3
14+
shuffleBits BingoSim.Simulation src/BingoSim/Simulation.hs:(121,1)-(128,39) 4.4 0.0
15+
next.result BingoSim.Prng src/BingoSim/Prng.hs:80:7-41 1.9 6.9
16+
17+
18+
individual inherited
19+
COST CENTRE MODULE SRC no. entries %time %alloc %time %alloc
20+
21+
MAIN MAIN <built-in> 193 0 0.0 0.0 100.0 100.0
22+
CAF GHC.Conc.Signal <entire-module> 290 0 0.0 0.0 0.0 0.0
23+
CAF GHC.Float <entire-module> 282 0 0.0 0.0 0.0 0.0
24+
CAF GHC.IO.Encoding <entire-module> 272 0 0.0 0.0 0.0 0.0
25+
CAF GHC.IO.Encoding.Iconv <entire-module> 270 0 0.0 0.0 0.0 0.0
26+
CAF GHC.IO.Handle.FD <entire-module> 261 0 0.0 0.0 0.0 0.0
27+
CAF Text.Printf <entire-module> 224 0 0.0 0.0 0.0 0.0
28+
CAF Text.Read.Lex <entire-module> 222 0 0.0 0.0 0.0 0.0
29+
CAF:col1 BingoSim.Board src/BingoSim/Board.hs:148:1-4 345 0 0.0 0.0 0.0 0.0
30+
col1 BingoSim.Board src/BingoSim/Board.hs:148:1-45 419 1 0.0 0.0 0.0 0.0
31+
CAF:col2 BingoSim.Board src/BingoSim/Board.hs:151:1-4 344 0 0.0 0.0 0.0 0.0
32+
col2 BingoSim.Board src/BingoSim/Board.hs:151:1-45 420 1 0.0 0.0 0.0 0.0
33+
CAF:col3 BingoSim.Board src/BingoSim/Board.hs:154:1-4 343 0 0.0 0.0 0.0 0.0
34+
col3 BingoSim.Board src/BingoSim/Board.hs:154:1-45 421 1 0.0 0.0 0.0 0.0
35+
CAF:col4 BingoSim.Board src/BingoSim/Board.hs:157:1-4 342 0 0.0 0.0 0.0 0.0
36+
col4 BingoSim.Board src/BingoSim/Board.hs:157:1-45 422 1 0.0 0.0 0.0 0.0
37+
CAF:col5 BingoSim.Board src/BingoSim/Board.hs:160:1-4 341 0 0.0 0.0 0.0 0.0
38+
col5 BingoSim.Board src/BingoSim/Board.hs:160:1-45 423 1 0.0 0.0 0.0 0.0
39+
CAF:col6 BingoSim.Board src/BingoSim/Board.hs:163:1-4 339 0 0.0 0.0 0.0 0.0
40+
col6 BingoSim.Board src/BingoSim/Board.hs:163:1-45 424 1 0.0 0.0 0.0 0.0
41+
CAF:dia1 BingoSim.Board src/BingoSim/Board.hs:124:1-4 354 0 0.0 0.0 0.0 0.0
42+
dia1 BingoSim.Board src/BingoSim/Board.hs:124:1-45 411 1 0.0 0.0 0.0 0.0
43+
CAF:dia2 BingoSim.Board src/BingoSim/Board.hs:127:1-4 353 0 0.0 0.0 0.0 0.0
44+
dia2 BingoSim.Board src/BingoSim/Board.hs:127:1-45 412 1 0.0 0.0 0.0 0.0
45+
CAF:lvl1_r64x BingoSim.Simulation <no location info> 311 0 0.0 0.0 0.0 0.0
46+
CAF:lvl3_r64z BingoSim.Simulation <no location info> 312 0 0.0 0.0 0.0 0.0
47+
CAF:lvl5_r64B BingoSim.Simulation <no location info> 313 0 0.0 0.0 0.0 0.0
48+
CAF:lvl6_r64C BingoSim.Simulation <no location info> 314 0 0.0 0.0 0.0 0.0
49+
runSimulation BingoSim.Simulation src/BingoSim/Simulation.hs:(68,1)-(84,41) 394 0 0.0 0.0 0.0 0.0
50+
mkState BingoSim.Prng src/BingoSim/Prng.hs:(56,1)-(58,39) 395 1 0.0 0.0 0.0 0.0
51+
CAF:main1 Main <no location info> 384 0 0.0 0.0 0.0 0.0
52+
main Main app/Main.hs:(10,1)-(12,30) 386 1 0.0 0.0 0.0 0.0
53+
CAF:main4 Main <no location info> 381 0 0.0 0.0 0.0 0.0
54+
CAF:row1 BingoSim.Board src/BingoSim/Board.hs:130:1-4 351 0 0.0 0.0 0.0 0.0
55+
row1 BingoSim.Board src/BingoSim/Board.hs:130:1-45 413 1 0.0 0.0 0.0 0.0
56+
CAF:row2 BingoSim.Board src/BingoSim/Board.hs:133:1-4 350 0 0.0 0.0 0.0 0.0
57+
row2 BingoSim.Board src/BingoSim/Board.hs:133:1-45 414 1 0.0 0.0 0.0 0.0
58+
CAF:row3 BingoSim.Board src/BingoSim/Board.hs:136:1-4 349 0 0.0 0.0 0.0 0.0
59+
row3 BingoSim.Board src/BingoSim/Board.hs:136:1-45 415 1 0.0 0.0 0.0 0.0
60+
CAF:row4 BingoSim.Board src/BingoSim/Board.hs:139:1-4 348 0 0.0 0.0 0.0 0.0
61+
row4 BingoSim.Board src/BingoSim/Board.hs:139:1-45 416 1 0.0 0.0 0.0 0.0
62+
CAF:row5 BingoSim.Board src/BingoSim/Board.hs:142:1-4 347 0 0.0 0.0 0.0 0.0
63+
row5 BingoSim.Board src/BingoSim/Board.hs:142:1-45 417 1 0.0 0.0 0.0 0.0
64+
CAF:row6 BingoSim.Board src/BingoSim/Board.hs:145:1-4 346 0 0.0 0.0 0.0 0.0
65+
row6 BingoSim.Board src/BingoSim/Board.hs:145:1-45 418 1 0.0 0.0 0.0 0.0
66+
main Main app/Main.hs:(10,1)-(12,30) 387 0 0.0 0.0 100.0 100.0
67+
main.\ Main app/Main.hs:11:13-37 388 1 0.0 0.0 100.0 100.0
68+
runSimulation BingoSim.Simulation src/BingoSim/Simulation.hs:(68,1)-(84,41) 389 1 0.7 0.0 100.0 100.0
69+
hasBingo BingoSim.Board src/BingoSim/Board.hs:(82,1)-(96,32) 410 100000 0.5 0.0 0.5 0.0
70+
randomBoard BingoSim.Simulation src/BingoSim/Simulation.hs:(108,1)-(110,35) 390 100000 0.5 0.2 98.8 100.0
71+
shuffleBits BingoSim.Simulation src/BingoSim/Simulation.hs:(121,1)-(128,39) 391 3600000 4.4 0.0 98.4 99.8
72+
next BingoSim.Prng src/BingoSim/Prng.hs:(79,1)-(91,40) 393 3500000 50.6 48.5 93.5 99.8
73+
next.result BingoSim.Prng src/BingoSim/Prng.hs:80:7-41 405 3500000 1.9 6.9 1.9 6.9
74+
shuffleBits.withRand BingoSim.Simulation src/BingoSim/Simulation.hs:(125,3)-(128,39) 396 3500000 16.5 31.2 40.4 44.4
75+
shuffleBits.withRand.bs' BingoSim.Simulation src/BingoSim/Simulation.hs:127:9-45 406 3500000 13.7 6.9 23.7 13.2
76+
swapBits BingoSim.Simulation src/BingoSim/Simulation.hs:(140,1)-(143,46) 408 3500000 10.0 6.3 10.0 6.3
77+
swapBits.x BingoSim.Simulation src/BingoSim/Simulation.hs:142:7-53 409 3182752 0.0 0.0 0.0 0.0
78+
shuffleBits.withRand.i BingoSim.Simulation src/BingoSim/Simulation.hs:126:9-41 404 3500000 0.2 0.0 0.2 0.0
79+
next.s0' BingoSim.Prng src/BingoSim/Prng.hs:87:7-27 403 3499999 0.0 0.0 0.0 0.0
80+
next.s1' BingoSim.Prng src/BingoSim/Prng.hs:86:7-27 402 3499999 0.2 0.0 0.2 0.0
81+
next.s2' BingoSim.Prng src/BingoSim/Prng.hs:84:7-26 399 3499999 0.2 0.0 0.2 0.0
82+
next.s2'' BingoSim.Prng src/BingoSim/Prng.hs:89:7-26 401 3499999 0.0 0.0 0.0 0.0
83+
next.s3' BingoSim.Prng src/BingoSim/Prng.hs:85:7-26 397 3499999 0.2 0.0 0.2 0.0
84+
next.s3'' BingoSim.Prng src/BingoSim/Prng.hs:90:7-31 398 3499999 0.0 0.0 0.0 0.0
85+
next.t BingoSim.Prng src/BingoSim/Prng.hs:82:7-35 400 3499999 0.0 0.0 0.0 0.0
86+
shuffleBits.n' BingoSim.Simulation src/BingoSim/Simulation.hs:124:3-12 392 3500000 0.5 0.0 0.5 0.0
87+
randomBoard.board BingoSim.Simulation src/BingoSim/Simulation.hs:109:7-26 407 100000 0.0 0.0 0.0 0.0
88+
runSimulation.rate BingoSim.Simulation src/BingoSim/Simulation.hs:81:7-58 425 1 0.0 0.0 0.0 0.0

src/BingoSim/Prng.hs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,21 @@
44
-- Haskell. The documentation and comments below come from the original C
55
-- sources.
66
--
7-
-- = License
8-
--
97
-- Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
108
--
119
-- To the extent possible under law, the author has dedicated all copyright
1210
-- and related and neighboring rights to this software to the public domain
1311
-- worldwide. This software is distributed without any warranty.
1412
--
1513
-- See <http://creativecommons.org/publicdomain/zero/1.0/>.
16-
1714
module BingoSim.Prng
18-
( State
15+
(
16+
-- * Seeding the generator
17+
State
1918
, mkState
19+
-- * Generating random numbers
2020
, next
21+
-- * Jumps
2122
, jump
2223
, longJump
2324
)
@@ -63,10 +64,19 @@ mkState s0 s1 s2 s3 = State s0 s1 s2 s3
6364
-- For generating just floating-point numbers, xoshiro256+ is even faster.
6465
--
6566
-- >>> let state = mkState 1 2 3 4
66-
-- >>> next state
67+
-- >>> next state (\rand _state' -> rand)
68+
-- 11520
69+
--
70+
-- Note: When porting to Haskell, we've explicitly chosen to make the API of
71+
-- 'next' in CPS-style (i.e., using a callback) to avoid always allocating a
72+
-- tuple for the result.
73+
--
74+
-- If you'd rather just have a tuple, you can pass @(,)@ as the callback:
75+
--
76+
-- >>> next state (,)
6777
-- (11520,mkState 7 0 262146 211106232532992)
68-
next :: State -> (Word64, State)
69-
next (State s0 s1 s2 s3) =
78+
next :: State -> (Word64 -> State -> a) -> a
79+
next (State s0 s1 s2 s3) f =
7080
let result = ((s1 * 5) `rotateL` 7) * 9
7181

7282
t = s1 `unsafeShiftL` 17
@@ -78,7 +88,7 @@ next (State s0 s1 s2 s3) =
7888

7989
s2'' = s2' `xor` t
8090
s3'' = s3' `rotateL` 45
81-
in (result, State s0' s1' s2'' s3'')
91+
in f result (State s0' s1' s2'' s3'')
8292

8393
-- | This is the jump function for the generator. It is equivalent
8494
-- to 2^128 calls to next(); it can be used to generate 2^128

src/BingoSim/Simulation.hs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,14 @@ shuffleBits
118118
-> Board
119119
-> Int -- ^ @n@: The current bit we're considering swapping or leaving alone (1-indexed).
120120
-> (Board, Prng.State)
121-
shuffleBits gen board 1 = (board, gen)
122-
shuffleBits gen (Board bs) n =
123-
let n' = n - 1
124-
(rand, gen') = next gen
125-
i = rand `mod` (fromIntegral n)
126-
bs' = swapBits bs n' (fromIntegral i)
127-
in shuffleBits gen' (Board bs') n'
121+
shuffleBits gen board 1 = (board, gen)
122+
shuffleBits gen (Board bs) n = next gen withRand
123+
where
124+
n' = n - 1
125+
withRand rand gen' =
126+
let i = rand `mod` (fromIntegral n)
127+
bs' = swapBits bs n' (fromIntegral i)
128+
in shuffleBits gen' (Board bs') n'
128129

129130
-- | Helper for swapping two specific bits.
130131
--

0 commit comments

Comments
 (0)