xrandom 0.3.0 copy "xrandom: ^0.3.0" to clipboard
xrandom: ^0.3.0 copied to clipboard

outdated

All-purpose, rock-solid random number generators focused on the reproducibility of tests on different platforms

xrandom #

Classes implementing all-purpose, rock-solid random number generators.

Library priorities:

  • generation of identical bit-accurate numbers regardless of the platform
  • reproducibility of the same random results in the future
  • high-quality randomness
  • performance

Algorithms are Xoshiro for quality and Xorshift for speed.

Speed #

Generating 50 million random numbers with AOT-compiled binary.

Time (lower is better) nextInt nextDouble nextBool
Random (dart:math) 1172 1541 1134
Xrandom 719 1126 710

Simplicity #

It's compatible with the standard Random

import 'package:xrandom/xrandom.dart';

final random = Xrandom();

var a = random.nextBool(); 
var b = random.nextDouble();
var c = random.nextInt(n);

var unordered = [1, 2, 3, 4, 5]..shuffle(random);

Reproducibility #

Xrandom's classes can also be created with expected method. It is made specifically for testing.

test('my test', () {
 final random = Xrandom.expected();
 // you'll get same sequence of numbers every time
 expect(random.nextInt(1000), 925);
 expect(random.nextInt(1000), 686);
 expect(random.nextInt(1000), 509); 
}); 

You can achieve the same determinism by creating the Random with a seed argument. However, this does not protect you from dart:math implementation updates.

The sequences produced by the expected() generators are intended to be reproducible.

(but not until the library reaches stable release status)

Which to choose #

You just want a random number:

final random = Xrandom(); // works on all platforms

quoteOfTheDay = quotes[random.nextInt(quotes.length)];

You need billions and billions of randoms in a non-repeating sequence:

final random = XrandomHq(); // works on mobile and desktop

for (var i=0; i<BILLIONS; i++)
 feedMonteCarloSimulation(random.nextDouble());

You tried to create XrandomHq on Node.js but got UnsupportedError:

final random = XrandomHqJs(); // works on all platforms

for (var i=0; i<BILLIONS; i++)
 feedMonteCarloSimulation(random.nextDouble());
Class The same as Mobile Desktop JS
Xrandom Xorshift32
XrandomHq Xoshiro256pp
XrandomHqJs Xoshiro128pp

Xrandom, XrandomHq, XrandomHqJs are easy-to-remember aliases.

Algorithms #

Class Arch Algorithm Algorithm author Published
Xorshift32 32 xorshift32 G. Marsaglia 2003
Xorshift64 64 xorshift64 G. Marsaglia 2003
Xorshift128 32 xorshift128 G. Marsaglia 2003
Xorshift128p 64 xorshift128+ S. Vigna 2015
Xoshiro128pp 32 xoshiro128++ 1.0 D. Blackman and S. Vigna 2019
Xoshiro256pp 64 xoshiro256++ 1.0 D. Blackman and S. Vigna 2019
Splitmix64 64 splitmix64 S. Vigna 2015

Compatibility #

You can safely use any classes on mobile and desktop platforms.

However, if you also target JavaScript (Web, Node.js), you will have to limit your choice.

Full compatibility table:

Class Is a Mobile Desktop JavaScript
Xorshift32 32-bit
Xorshift128 32-bit
Xoshiro128pp 32-bit
Xorshift64 64-bit
Xorshift128p 64-bit
Xoshiro256pp 64-bit
Splitmix64 64-bit

If you try to create a JavaScript-incompatible object in JavaScripts-compiled code, an UnsupportedError will be thrown.

Speed optimizations #

Raw bits #

The nextInt32() and nextInt64() return the raw output of the generator.

Method Returns Equivalent of
nextInt32() 32-bit unsigned nextInt(0xFFFFFFFE)+1
nextInt64() 64-bit signed nextInt(0xFFFFFFFFFFFFFFFE)+1
Raw bits benchmarks
Time (lower is better) nextInt nextInt32 nextInt64
Random (dart:math) 1208 - -
Xorshift32 719 409 -
Xorshift64 1114 814 838
Xorshift128 907 618 -
Xorshift128p 1162 854 952
Xoshiro128pp 1228 912 -
Xoshiro256pp 1746 1498 2039
Splitmix64 1248 931 782

Rough double #

nextFloat, unlike nextDouble, prefers speed to accuracy. It transforms a single 32-bit integer into a double. Therefore, the result is limited to a maximum of 2^32-1 values. But it's still a double with four billion shades.

Rough double benchmarks
Time (lower is better) nextDouble nextFloat
Random (dart:math) 1653 -
Xorshift32 1126 407
Xorshift64 1011 825
Xorshift128 1461 622
Xorshift128p 1141 860
Xoshiro128pp 2095 923
Xoshiro256pp 2294 1488
Splitmix64 1098 932

More benchmarks #

Time (lower is better) nextInt nextDouble nextBool
Random (dart:math) 1208 1653 1177
Xorshift32 719 1126 710
Xorshift64 1114 1011 685
Xorshift128 907 1461 719
Xorshift128p 1162 1141 694
Xoshiro128pp 1228 2095 726
Xoshiro256pp 1746 2294 721
Splitmix64 1248 1098 688

All the benchmarks on this page are from AOT-compiled binaries running on AMD A9-9420e with Ubuntu 20.04. Time is measured in milliseconds.

Consistency #

The library has been thoroughly tested to match reference numbers generated by C algorithms. The sources in C are taken directly from scientific publications or the reference implementations by the inventors of the algorithms. The Xorshift128+ results are also matched to reference values from JavaScript xorshift library, which tested the 128+ similarly.

Testing is done in the GitHub Actions cloud on Windows, Ubuntu, and macOS in VM and Node.js modes.

11
likes
0
pub points
77%
popularity

Publisher

verified publisherrevercode.com

All-purpose, rock-solid random number generators focused on the reproducibility of tests on different platforms

Repository (GitHub)
View/report issues

License

unknown (license)

More

Packages that depend on xrandom