src.it.unimi.dsi.util.package-info Maven / Gradle / Ivy
/**
* Miscellaneaous utility classes.
*
*
Pseudorandom number generators
*
* Warning: From version 2.4.1, the methods {@code nextInt()},
* {@code nextInt(int)} and {@code nextLong(int)} of
* {@link it.unimi.dsi.util.XoRoShiRo128PlusRandomGenerator}/{@link it.unimi.dsi.util.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.
*
* - {@link it.unimi.dsi.util.XoRoShiRo128PlusRandom
xoroshiro128+
} is a fast, high-quality generator.
* It has strong statistical properties and it is the fastest generator we provide. Its period (2128 − 1) is sufficient
* for any application with a reasonable amount of parallelism. It is our suggestion for an all-purpose generator. It is the
* default generator in Erlang.
* - {@link it.unimi.dsi.util.SplitMix64Random SplitMix64} is a fast, high-quality generator, but it has a relatively short period (264) so it should
* not be used to generate very long sequences (the rule of thumb to have a period greater than the square of the length of the sequence you want to generate).
* It is a non-splittable version of {@link java.util.SplittableRandom},
* and thus conceptually identical to {@link java.util.concurrent.ThreadLocalRandom} (note that Java 7's version
* was identical to {@link java.util.Random}, instead). We use it to initialize the state of all other generators starting from a 64-bit seed.
*
- {@link it.unimi.dsi.util.XorShift1024StarPhiRandom
xorshift1024*φ
} is fast, high-quality
* and provides a long period (21024 − 1) for massive parallel computations.
*
*
* {@link it.unimi.dsi.util.XoRoShiRo128PlusRandom xoroshiro128+
}, {@link it.unimi.dsi.util.XorShift128PlusRandom xorshift128+
} and
* {@link it.unimi.dsi.util.XorShift1024StarPhiRandom xorshift1024*φ
} provide
* {@linkplain it.unimi.dsi.util.XoRoShiRo128PlusRandom#jump() jump functions} which make it possible to generate long non-overlapping sequences,
* and {@linkplain it.unimi.dsi.util.XoRoShiRo128PlusRandom#split() split functions} in the spirit of {@link java.util.SplittableRandom SplittableRandom}.
*
*
A table summarizing timings is provided below. The timings were measured on an
* Intel® Core™ i7-7700 CPU @ 3.60GHz.
* 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 {@code perfasm} profiler the JMH overhead was estimated at ≈1ns per call.
*
*
*
* {@link java.util.Random Random}
* ThreadLocalRandom
* SplittableRandom
* {@link it.unimi.dsi.util.SplitMix64RandomGenerator SplitMix64}
* {@link it.unimi.dsi.util.XoRoShiRo128PlusRandom xoroshiro128+
}
* {@link it.unimi.dsi.util.XorShift128PlusRandom xorshift128+
}
* {@link it.unimi.dsi.util.XorShift1024StarPhiRandom xorshift1024*φ
}
*
* nextInt() 7.387 1.490 1.329 1.325 1.521 1.459 2.235
* nextLong() 15.772 1.512 1.389 1.450 1.424 1.437 2.088
* nextDouble() 16.052 2.140 2.400 2.396 2.283 2.012 3.012
* nextInt(100000) 7.388 2.322 2.731 2.878 2.303 2.475 3.525
* nextInt(229+228) 11.514 7.303 7.400 3.167 2.432 2.611 3.728
* nextInt(230) 7.398 1.587 1.452 1.526 1.526 1.807 2.238
* nextInt(230 + 1) 20.988 14.583 15.022 2.950 2.306 2.601 3.61
* nextInt(230 + 229) 11.503 7.413 7.387 3.148 2.438 2.617 3.727
* nextLong(1000000000000) 2.551 3.006 2.989 2.382 2.618 3.621
* nextLong(262 + 1) 15.100 15.414 15.540 12.649 13.821 16.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 {@link java.util.Random}, overriding (as usual) the {@link java.util.Random#next(int) next(int)} method. Nonetheless,
* since the generators are all inherently 64-bit also {@link java.util.Random#nextInt() nextInt()}, {@link java.util.Random#nextFloat() nextFloat()},
* {@link java.util.Random#nextLong() nextLong()}, {@link java.util.Random#nextDouble() nextDouble()}, {@link java.util.Random#nextBoolean() nextBoolean()}
* and {@link java.util.Random#nextBytes(byte[]) nextBytes(byte[])} have been overridden for speed (preserving, of course, {@link java.util.Random}'s semantics).
*
*
Warning: Before version 2.4.1, {@link java.util.Random#nextDouble() nextDouble()} and {@link java.util.Random#nextFloat() 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 {@code nextDoubleFast()}.
*
*
If you do not need an instance of {@link java.util.Random}, or if you need a {@link org.apache.commons.math3.random.RandomGenerator} to use
* with Commons Math, there is for each generator a corresponding {@link org.apache.commons.math3.random.RandomGenerator RandomGenerator}
* implementation, which indeed we suggest to use in general if you do not need a generator implementing {@link java.util.Random}.
*/
package it.unimi.dsi.util;