splitmix
Fast Splittable PRNG
| LTS Haskell 24.17: | 0.1.3.1 | 
| Stackage Nightly 2025-10-31: | 0.1.3.1 | 
| Latest on Hackage: | 0.1.3.1 | 
splitmix-0.1.3.1@sha256:d0002f3fb16a2cc5ba8afd47a6657726386edccfe8853d310e3479fe3b45201b,6552Module documentation for 0.1.3.1
- System- System.Random
 
splitmix
Pure Haskell implementation of SplitMix pseudo-random number generator.
dieharder
Dieharder is a random number generator (rng) testing suite. It is intended to test generators, not files of possibly random numbers as the latter is a fallacious view of what it means to be random. Is the number 7 random? If it is generated by a random process, it might be. If it is made up to serve the purpose of some argument (like this one) it is not. Perfect random number generators produce “unlikely” sequences of random numbers – at exactly the right average rate. Testing a rng is therefore quite subtle.
time $(cabal-plan list-bin splitmix-dieharder) splitmix
The test-suite takes around half-an-hour to complete. From 30 runs, 2.49% were weak (3247 passed, 83 weak, 0 failed).
In comparison, built-in Marsenne Twister test takes around 15min.
time dieharder -a
benchmarks
benchmarking list 64/random
time                 1.317 ms   (1.303 ms .. 1.335 ms)
                     0.998 R²   (0.998 R² .. 0.999 R²)
mean                 1.380 ms   (1.365 ms .. 1.411 ms)
std dev              70.83 μs   (37.26 μs .. 131.8 μs)
variance introduced by outliers: 39% (moderately inflated)
benchmarking list 64/tf-random
time                 141.1 μs   (140.4 μs .. 142.1 μs)
                     0.999 R²   (0.998 R² .. 1.000 R²)
mean                 145.9 μs   (144.6 μs .. 150.4 μs)
std dev              7.131 μs   (3.461 μs .. 14.75 μs)
variance introduced by outliers: 49% (moderately inflated)
benchmarking list 64/splitmix
time                 17.86 μs   (17.72 μs .. 18.01 μs)
                     0.999 R²   (0.998 R² .. 1.000 R²)
mean                 17.95 μs   (17.75 μs .. 18.47 μs)
std dev              1.000 μs   (444.1 ns .. 1.887 μs)
variance introduced by outliers: 64% (severely inflated)
benchmarking tree 64/random
time                 800.3 μs   (793.3 μs .. 806.5 μs)
                     0.999 R²   (0.998 R² .. 0.999 R²)
mean                 803.2 μs   (798.1 μs .. 811.2 μs)
std dev              22.09 μs   (14.69 μs .. 35.47 μs)
variance introduced by outliers: 18% (moderately inflated)
benchmarking tree 64/tf-random
time                 179.0 μs   (176.6 μs .. 180.7 μs)
                     0.999 R²   (0.998 R² .. 0.999 R²)
mean                 172.7 μs   (171.3 μs .. 174.6 μs)
std dev              5.590 μs   (4.919 μs .. 6.382 μs)
variance introduced by outliers: 29% (moderately inflated)
benchmarking tree 64/splitmix
time                 51.54 μs   (51.01 μs .. 52.15 μs)
                     0.999 R²   (0.998 R² .. 0.999 R²)
mean                 52.50 μs   (51.93 μs .. 53.55 μs)
std dev              2.603 μs   (1.659 μs .. 4.338 μs)
variance introduced by outliers: 55% (severely inflated)
Note: the performance can be potentially further improved when GHC gets SIMD Support.
Changes
0.1.3.1
- Fix linking issue symbol not found in flat namespace '_kSecRandomDefault'when using splitmix in TH on macOS.
0.1.3
- Use system specific entropy/randomess sources to initialise the default generator.
Specifically SecRandomCopyByteson Apple platforms andRtlGenRandomon Windows.
0.1.2
- Use getentropyfor initialisation on unix-like systems (i.e. not Windows).
0.1.1
- Drop support for GHCs prior 8.6.5
- Support GHC-9.12
0.1.0.4
- Add TestU01 test-suite
0.1.0.3
- 
Fix oops bugs in 0.1.0.2 - 
It’s lowercase windows.h. I blame Microsoft docs for using capital caseWindows.hin the docs. https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocessid
- 
accidental shiftLvsshiftRmixup for 32-bit generator initialization. Doesn’t affect Linux.
 
- 
0.1.0.2
- Drop timedependency in favour of handcoded initialization- On Unix platforms we use /dev/urandomif it exists, otherwise usegettimeofday,clockandgetpid.
- On Windows we use GetCurrentProcessID,GetCurrentThreadId(),GetTickCount,GetSystemTimeandQueryPerformanceCounter.
- On GHCJS use Math.random()
- Using timeis a fallback option (e.g. for Hugs).
 
- On Unix platforms we use 
0.1.0.1
- Add INLINEABLEpragmas tobitmaskWithRejection*functions
- Support GHC-9.0
0.1
- Drop randomdependency unconditionally. https://github.com/phadej/splitmix/issues/34
0.0.5
- Add nextInteger
- Use smaller range in bitmaskWithRejection32and64, when upper bound is 2^n - 1. This changes generated values when they were on the boundary.
0.0.4
- Add bitmaskWithRejection32'andbitmaskWithRejection64'which generate numbers in closed range[0, n]. Unticked variants generate in closed-open range[0, n).
0.0.3
- Add System.Random.SplitMix32module
- Add bitmaskWithRejection32andbitmaskWithRejection64functions
- Add nextWord32,nextTwoWord32andnextFloat
- Add randomflag, dropping dependency onrandom(breaks things, e.g.QuickCheck, when disabled).
0.0.2
- Support back to GHC-7.0
- Add Read SMGeninstance
0.0.1
- Add NFData SMGeninstance
- Fix a bug. http://www.pcg-random.org/posts/bugs-in-splitmix.html The generated numbers will be different for the same seeds!
