and by random changes I mean changes to Random
. Here’s what’s affected by the change:
Performance
The old algorithm used by Mono was not very efficient, even less on system where floating-point computations are slow. The new algorithm, JKISS, is faster and does not require floating-point math unless you ask for a System.Double
value.
The requirement to use floating point, basically calling the protected Sample
method, was removed in .NET 2.0 – but never implemented in Mono.
E.g. Using Mono 3.2.3, JIT, x86_64 filling a one megabyte buffer 1024 times with random data took:
- 13 723 ms with the old code
- 7 244 ms with the new code
The difference is more visible on ARM devices where floating-point computation are not very fast. E.g. The same test built/executed with Xamarin.iOS 7.0, AOT, ARMv7+LLVM (iPod 4th gen running iOS7) took:
- 87 910 ms with the old code
- 28 658 ms with the new code
Period
Beside not being very efficient the old algorithm had a short period (2^55-1) before it starts repeating the same pseudo random data stream. The new algorithm has a longer period (2^127).
That being said the new algorithm is not meant for cryptographic usage. In fact everything that does not require speed (i.e. a lot of random data) or predictability should use System.Security.Cryptography.RNGCryptoServiceProvider
.
Random API Q&A
Q: Does calling new Random (...).Next ()
returns a random integer ?
A: Yes, but not 32 bits of randomness, i.e. the API returns a non-negative System.Int32
value, so [0,Int32.MaxValue]
. The only way to get negative integers is to use the Next(int,int)
overload.
Backward Compatibility
If you depend on predicable random numbers, i.e. always the same random stream from the same seed (e.g. common in simulation software) then the change of algorithm will affect you.
In such case the best advice is to bundle your own random implementation inside your application (and, of course, have your own unit tests) to ensure no options/bugs interfere with your results. That way you’re shielded from platform and/or language changes.
> If you depend on predicable random numbers
Trying to understand… this breaks the Random(Int32) constructor?
http://msdn.microsoft.com/en-us/library/ctssatww.aspx
> Providing an identical seed value to different Random objects causes each instance to produce identical sequences of random numbers.
No. If you create two identical instances of, let’s say,, `a = Random(42);` and `b = Random(42);`, they will both give you the same pseudo random stream.
If you saved the `a` stream with a old version of Mono and compare it to `b` produced by a new version of Mono then they will be different. That’s just like if you generated `a` with MS.NET and `b` with Mono (they also would be different).