D-Programming-Language/phobos — pull request #1717 by Zshazz (2013-11-25 04:14:36+00:00)
Title: Fix issue 11598 - uniform could be faster for integrals

See:
https://d.puremagic.com/issues/show_bug.cgi?id=11598
http://forum.dlang.org/thread/jnu1an$rjr$1@digitalmars.com

These changes retain the uniform quality of this function while, in the common case, cutting the number of division operations in half.

Additionally, extra unittests were added to assure that all of the bounds were tested properly.

Example benchmark:

import std.stdio, std.datetime, std.random, std.range, std.algorithm;
alias RngType = Xorshift;

RngType rnd;
int[] arr;

void main() {
rnd = RngType(328374);
arr = iota(100_000).array();
auto bench = benchmark!(shuffleTest)(100);
writeln(bench[].map!(e => e.msecs), " ms");
}

void shuffleTest() {
auto cpRnd = rnd.save();
arr.randomShuffle(cpRnd);
}

Results on my machine:
Old `uniform` (using `Xorshift`): 686ms
New `uniform` (using `Xorshift`): 451ms
New `uniform` (using `Mt19937`): 597ms

So, as you can see, this new `uniform` is significantly faster than the old. In code that uses the integral `uniform` heavily (for instance, `randomShuffle`) it's possible to use the higher quality `Mt19937` and still be faster than the old `uniform` using the much faster `XorShift`.