Package it.unimi.dsi.util

package it.unimi.dsi.util
Miscellaneous utility classes

Pseudorandom number generators

Warning: before release 2.6.3, the split() method of all generators would not alter the state of the caller, and it would return instances initialized in the same way if called multiple times. This was a major mistake in the implementation and it has been fixed, but as a consequence the output of the caller after a call to split() is now different, and the result of split() is initialized in a different way.

We provide a number of fast, high-quality PRNGs with different features. You can get detailed information about the generators at our PRNG page, together with a reasoned guide to the choice of the generator that's right for you.

Note that starting with Java 17 xoroshiro128++ and xoshiro256++ are part of the package java.util.random.

A table summarizing timings is provided below. The timings were measured on an Intel® Core™ i7-8700B CPU @3.20GHz using 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.

Timings in nanoseconds for a few generators
Random ThreadLocalRandom SplittableRandom SplitMix64 xoroshiro128++ xoroshiro128** xoroshiro128+ xoshiro256++ xoshiro256** xoshiro256+ xorshift1024*φ
nextLong() 14.419 1.252 1.283 1.241 1.428 1.574 1.295 1.738 1.884 1.653 1.901
nextInt(100000) 6.715 2.045 2.499 2.543 2.336 2.594 1.202 2.607 2.954 2.367 3.119
nextDouble() 14.458 1.876 2.161 2.176 1.918 2.219 1.853 2.304 2.503 2.112 2.755

Note that generators that are extremely fast in C, such as xoshiro256+, do not perform particularly well in Java, most likely because of the cost of accessing variables, which rises as the size of the state space grows. Indeed, smaller-state generators are faster. Moreover, generators based on the ++ scrambler are slightly faster than those based on the ** scrambler, contrarily to what happens in C.

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).

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.