Fixed-size arrays and randomShuffle()
Chris Cain
clcain at uncg.edu
Thu May 3 13:07:30 PDT 2012
OK, I took a look at your example, and I saw the kind of
performance you were seeing.
I performed an investigation on what could cause such a disparity
and came up with a conclusion. The answer is two things: First of
all, as noted above, D's default generator is a mersenne twister
RNG. You can emulate Java's RNG like so:
auto rng = LinearCongruentialEngine!(ulong,
25214903917uL, 11uL, 2uL^^48uL)();
Once I equalized that, I looked into the various methods that are
called and settled in on uniform.
https://github.com/D-Programming-Language/phobos/blob/master/std/random.d#L1154
As you can see, there's a division at line 1154 and another at
line 1158. This means there's a minimum of two division
operations every time uniform is called. Now, normally this isn't
a big deal, but if we really want maximum performance, we need to
eliminate at least one.
If you replace lines 1154-1161 (auto bucketSize ... to return...)
with:
CountType rnum, result;
do
{
rnum = cast(CountType) uniform!CountType(urng);
result = rnum % count;
}
while (rnum > count &&
(rnum - result + (count - 1)) < (rnum - result - 1));
return cast(typeof(return)) (min + result);
Then the time taken shrinks down to roughly the same (within a
tenth of a second) as Java.
I'll probably clean this up (and write some comments on how this
works) and see about submitting it as a patch unless anyone sees
anything wrong with this approach.
More information about the Digitalmars-d-learn
mailing list