Closed sethladd closed 9 years ago
For a reference to a JavaScript implementation of Mersenne Twister, see https://gist.github.com/banksean/300494
I've worked a lot on the RNG for V8 and Dart, and switching from the current one to Mersenne Twister would be fine with me. It looks like it would be comparable in speed to the current one, and we have had some problems with the non-randomness of the current one.
The fact that it has been adopted by so many other software systems is a good indication that we should consider it.
Each instance of Random would be about 2 kb, much larger than it is now. But that should not be an issue. And the latency of getting a random number is non-uniform. Every 600th random number takes hundreds of times longer than all the others to generate. But the average time is low.
But speed is pretty important - we made a change that made the RNG twice as slow, and then reverted it because that was unacceptable.
Switching to Mersenne Twister is a separate issue from fixing the dart2js implementation of math.Random.
Removed Priority-Unassigned label. Added Priority-Medium label.
Didn't mean to imply Mersenne Twister is the solution. Just an option to port to a package in the meantime.
I originally implemented dart2js's Random completely in terms of the JS Math.random, which has no seed. I'll add a version that mirrors the VM's Random and use that if the user provides a seed.
We can still have other Random algorithms in a library (Mersenne, Well512, etc), that users can pick if they know that they need a particular property. They are all more heavy-weight than the current version.
Set owner to @lrhn. Added Started label.
This comment was originally written by svenpanne@chromium.org
Totally unsolicited side note: I think the right way to do random numbers is to disentangle responsibilities which are blurred in a lot of standard libraries, including the ones for Dart (if I see it correctly):
* There is a need for different kinds of (pseudo-)entropy sources, with varying characteristics for cryptographic strength, speed, latency, etc.
* There is a need for different kind of distributions (uniform, normal, binomial, ...).
There is no way to get this right for all use cases with a simple single class/method. You have to keep the 2 notions above separate and provide several implementations which users can easily plug together and extend if needed. It is OK to have a simple default combination, but OTOH if you do the design right, there is almost no need for it because it is so simple to do for yourself. Dart and its libraries are still very young, so change this while it's easily possible.
BTW: C++ gets this right nowadays (http://www.cplusplus.com/reference/random/), same for Haskell (http://hackage.haskell.org/package/random-1.0.1.1/docs/System-Random.html).
Just my 2c, and sorry if I misunderstood Dart's libraries, I just had a quick look...
I agree. It would make sense to have a way to get entrophy (void getEntrophyBytes(int count, List<int> target)) so that libraries can add other Random implementations. There is a feature request for that already.
The current implementations is primarily quick and reasonably well behaving, pretty much like JS's Math.random.
I could see a random package adding a number of different Random classes, MersenneRandom, Well512Random, etc., so a discriminating user can pick the one they need, and those who don't really care about details can just use dart:math's default Random.
Thanks Lasse!
This code:
import 'dart:math';
main() { var rand = new Random(new DateTime.now().millisecondsSinceEpoch); for (var i = 0; i < 10; i++) print(rand.nextDouble()); }
Is compiled to:
main: function() { var i, line; P.DateTime$_now(); for (i = 0; i < 10; ++i) { line = C.JSDouble_methods.toString$0(Math.random()); H.printToConsole(line); }
Notice the seed is dropped.