Skip navigation links

Package it.unimi.dsi.util

Miscellaneaous utility classes.

See: Description

Package it.unimi.dsi.util Description

Miscellaneaous utility classes.

Pseudorandom number generators

Warning: From version 2.4.1, the methods nextInt(), nextInt(int) and nextLong(int) of XoRoShiRo128PlusRandomGenerator/XoRoShiRo128PlusRandom implement a different logic that prefers the high bits. The results will be thus different from previous versions.

We provide a number of fast, high-quality PRNGs with different features.

xoroshiro128+, xorshift128+ and xorshift1024*φ provide jump functions which make it possible to generate long non-overlapping sequences, and split functions in the spirit of SplittableRandom.

A table summarizing timings is provided below. The timings were measured on an Intel® Core™ i7-7700 CPU @ 3.60GHz (Kaby Lake). Note that we test several different method parameters to highlight the different strategies used to generate numbers in a range, as the rejection-based algorithm used by all generators can be based on integer or long inputs, and the results are quite different. For example, on modern, 64-bit CPUs Java's strategy of applying rejection to 32-bit integers does not pay off (see the timings for nextInt(230 + 1)).

The timings are very different from previous versions, but they should be more reliable, as they are now obtained by means of JMH microbenchmarks. The JMH timings were decreased by 1ns, as using the low-level perfasm profiler the JMH overhead was estimated at ≈1ns per call.

Random ThreadLocalRandom SplittableRandom SplitMix64 xoroshiro128+ xorshift128+ xorshift1024*φ
nextInt() 7.3871.4901.3291.3251.5211.4592.235
nextLong() 15.7721.5121.3891.4501.4241.4372.088
nextDouble() 16.0522.1402.4002.3962.2832.0123.012
nextInt(100000) 7.3882.3222.7312.8782.3032.4753.525
nextInt(229+228) 11.5147.3037.4003.1672.4322.6113.728
nextInt(230) 7.3981.5871.4521.5261.5261.8072.238
nextInt(230 + 1) 20.98814.58315.0222.9502.3062.6013.61
nextInt(230 + 229) 11.5037.4137.3873.1482.4382.6173.727
nextLong(1000000000000) 2.5513.0062.9892.3822.6183.621
nextLong(262 + 1) 15.10015.41415.54012.64913.82116.805

The quality of all generators we provide is very high: for instance, they perform better than WELL1024a or MT19937 (AKA the Mersenne Twister) in the TestU01 BigCrush test suite. More details can be found on the xoroshiro+/xorshift*/xorshift+ generators and the PRNG shootout page.

For each generator, we provide a version that extends Random, overriding (as usual) the next(int) method. Nonetheless, since the generators are all inherently 64-bit also nextInt(), nextFloat(), nextLong(), nextDouble(), nextBoolean() and nextBytes(byte[]) have been overridden for speed (preserving, of course, Random's semantics).

Warning: Before version 2.4.1, nextDouble() and nextFloat() were using a multiplication-free conversion that was significantly faster. However, the technique can generate only dyadic rationals of the form k / 2−52, instead of the standard k / 2−53, so you were generating half of values (essentially, the lowest bit of the mantissa would always be zero: this can be fixed with a test, but then the technique is not so fast anymore). Now the code performs the standard multiplication conversion: the only difference is that in half of the output there might be a last binary digit set to one. The old multiplication-free implementation is available under the name nextDoubleFast().

If you do not need an instance of Random, or if you need a RandomGenerator to use with Commons Math, there is for each generator a corresponding RandomGenerator implementation, which indeed we suggest to use in general if you do not need a generator implementing Random.

Skip navigation links