On 22-nov-10, at 16:11, tn wrote:

bearophile Wrote:

Some kind of little D programs I write need a lot of random values, and tests have shown me that std.random.uniform is slow.

So I have suggested to add a faster special case to generate a random double in [0.0, 1.0), see:
http://d.puremagic.com/issues/show_bug.cgi?id=5240

Bye,
bearophile


I did some testing with different combinations of types and boundary types. The problem noticed is a bit different to the one bearophile mentioned. Here is my test code:

--------------------
import std.conv;
import std.date;
import std.random;
import std.stdio;

void test(T, string boundaries)() {
        void fun() {
                uniform!(boundaries, T, T)(cast(T)0, cast(T)1000);
        }
writefln("%-8s %s %6d", to!string(typeid(T)), boundaries, benchmark!fun(10_000_000)[0]);
}

void testBoundaries(T)() {
        test!(T, "[]")();
        test!(T, "[)")();
        test!(T, "(]")();
        test!(T, "()")();
        writeln();
}

void main() {
        testBoundaries!(int)();
        testBoundaries!(long)();
        testBoundaries!(float)();
        testBoundaries!(double)();
        testBoundaries!(real)();
}
--------------------

And here are the results for 10 million calls of uniform (columns are: type, boundaries, elapsed time):

--------------------
int      []     271
int      [)     271
int      (]     283
int      ()     285

long     []     372
long     [)     399
long     (]     401
long     ()     397

float    []     286
float    [)     374
float    (]    5252
float    ()    5691

double   []     348
double   [)     573
double   (]    5319
double   ()    5875

real     []     434
real     [)     702
real     (]    2832
real     ()    3056
--------------------

In my opinion floating point uniforms with (] or () as boundary types are unacceptably slow. I had to use 1 - uniform!"[)"(0.0, 1.0) instead of uniform!"(]"(0.0, 1.0) because of this issue. I would also expect versions using float and double to be faster than the version using real.

-- tn
I suspect that the default random generator I have implemented (in blip & tango) is faster than phobos one, I did not try to support all possibilities, with floats just () and high probability (), but possible boundary values due to rounding when using an non 0-1 range, but I took lot of care to initialize *all* bits uniformly. The problem you describe looks like a bug though, if done correctly one should just add an if or two to the [] implementation to get () with very high probability.

Fawzi

Reply via email to