[Ironruby-core] rand() needs a seed?
Curt Hagenlocher
curth at microsoft.com
Sun Jul 6 14:49:22 EDT 2008
Something like that, yes, but making it a static member of KernelOps means that we have to pay the construction cost during startup. For a function as infrequently used as "rand", it might be better to initialize it more lazily.
From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Johan Danforth
Sent: Sunday, July 06, 2008 9:51 AM
To: ironruby-core at rubyforge.org
Subject: Re: [Ironruby-core] rand() needs a seed?
Like this?
private static readonly Random rndGen = new Random();
[RubyMethod("rand", RubyMethodAttributes.PrivateInstance)]
[RubyMethod("rand", RubyMethodAttributes.PublicSingleton)]
public static double Rand(CodeContext/*!*/ context, object self) {
lock(rndGen) return rndGen.NextDouble();
}
[RubyMethod("rand", RubyMethodAttributes.PrivateInstance)]
[RubyMethod("rand", RubyMethodAttributes.PublicSingleton)]
public static object Rand(CodeContext/*!*/ context, object self, int limit) {
if (limit == 0) return Rand(context, self);
lock (rndGen) return RuntimeHelpers.Int32ToObject((int)(rndGen.NextDouble() * (limit - 1)));
}
[RubyMethod("rand", RubyMethodAttributes.PrivateInstance)]
[RubyMethod("rand", RubyMethodAttributes.PublicSingleton)]
public static object Rand(CodeContext/*!*/ context, object self, double limit) {
if (limit < 1) return Rand(context, self);
lock (rndGen) return RuntimeHelpers.Int32ToObject((int)(rndGen.NextDouble() * (limit - 1)));
}
I put a lock() on each call as well, because I believe the Next-methods aren't thread safe. Works for me.
/Johan
From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Curt Hagenlocher
Sent: den 6 juli 2008 17:16
To: ironruby-core at rubyforge.org
Subject: Re: [Ironruby-core] rand() needs a seed?
By default, the parameterless constructor of the System.Random class (which is what we're using) uses the system time as the initial seed. Every time you ask for a random number, we create a new Random object, and in a tight loop like yours, they'll probably all get the same seed.
We should probably create a single Random object the first time that one is requested and store it in the RubyContext.
From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Johan Danforth
Sent: Sunday, July 06, 2008 7:28 AM
To: ironruby-core at rubyforge.org
Subject: [Ironruby-core] rand() needs a seed?
I'm a noob Ruby user, but IronRuby behaves different from other Ruby implementations that I've tried, in IronRuby (rev 121) this code:
100.times {p rand(100)}
Often returns the same value for (almost) all iterations, like this:
2
2
2
2
2
2
2
2
...and so on...
Works as designed? Need to seed it or something?
/Johan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20080706/7b20dc56/attachment-0001.html>
More information about the Ironruby-core
mailing list