Faster uniform() in [0.0 - 1.0(

Fawzi Mohamed fawzi at gmx.ch
Mon Nov 22 07:38:37 PST 2010


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


More information about the Digitalmars-d mailing list