Avoid most of the (small) regressions for seeded and derived Random instances (#57530)
authorStephen Toub <stoub@microsoft.com>
Tue, 17 Aug 2021 15:07:31 +0000 (11:07 -0400)
committerGitHub <noreply@github.com>
Tue, 17 Aug 2021 15:07:31 +0000 (11:07 -0400)
commitf7633f498a8be34bee739b240a0aa9ae6a660cd9
tree1f98e907f8b465e8909160be3e5a242ec2699005
parente6d37d7aa11ab76e7deba949f93d0cfb1c3bb743
Avoid most of the (small) regressions for seeded and derived Random instances (#57530)

* Split Random compat implementation to address most regressions

When we introduced the new Random algorithm, we did so by factoring the old algorithm out into an implementation strategy class that is instantiated for all use other than `new Random()`.  This ends up penalizing other uses (providing a seed and/or deriving from Random) by adding more virtual dispatch than is strictly necessary, in particular for `new Random(seed)`.  This PR negates most of that (expected) regression by splitting the compat implementation in two, one class for `new Random(seed)` and one for `new DerivedRandom()`/`new DerivedRandom(seed)`; the former no longer needs to make virtual calls back out to the parent type.  The former is also one that a consumer can't really do anything to improve, whereas in the derived case, the derivation may override to provide a more optimal implementation.

* Change NextUInt64 implementation to reduce number of calls

We haven't shipped this yet, so we can change its implementation to make 3 calls instead of 8 and to delegate to a different overload of Next.

* Consolidate NextBytes to use span
src/libraries/System.Private.CoreLib/src/System/Random.Net5CompatImpl.cs
src/libraries/System.Private.CoreLib/src/System/Random.cs
src/libraries/System.Runtime.Extensions/tests/System/Random.cs