public static void QuickStart_RandomVault() { // RandomVault is a random number pool. // It's thread-safe and faster than lock in most cases. var mt = new MersenneTwister(); // Create a random generator. var rv = new RandomVault(() => mt.NextUInt64(), x => mt.NextBytes(x)); // Specify NextULong() or NextBytes() or both delegates, and forget about mt. Console.WriteLine("RandomVault:"); Console.WriteLine(rv.NextInt64()); Console.WriteLine(rv.NextDouble()); }
public static void Test1() { var mt2 = new MersenneTwister(new ulong[] { 0x12345UL, 0x23456UL, 0x34567UL, 0x45678UL }); var poolSliding = new RandomVault(() => mt2.NextUInt64(), x => mt2.NextBytes(x)); Debug.Assert(poolSliding.NextUInt64() == 7266447313870364031UL); for (var i = 0; i < 20000; i++) { poolSliding.NextUInt64(); } var mt3 = new MersenneTwister(new ulong[] { 0x12345UL, 0x23456UL, 0x34567UL, 0x45678UL }); var poolConcurrentQueue = new RandomPoolConcurrentQueue(() => mt3.NextUInt64(), x => mt3.NextBytes(x)); Debug.Assert(poolConcurrentQueue.NextULong() == 7266447313870364031UL); for (var i = 0; i < 20000; i++) { poolConcurrentQueue.NextULong(); } }
public void Test1() { var xo = new Xoshiro256StarStar(42); var rv = new RandomVault(() => xo.NextUInt64(), x => xo.NextBytes(x)); DoubleToString(rv.NextDouble()).Is("0.0838629710598822"); DoubleToString(rv.NextDouble()).Is("0.3789802506626686"); DoubleToString(rv.NextDouble()).Is("0.6800434110281394"); DoubleToString(rv.NextDouble()).Is("0.9246929453253876"); DoubleToString(rv.NextDouble()).Is("0.9918039142821028"); string DoubleToString(double d) => d.ToString("F16"); rv.NextUInt64().Is(14199186830065750584ul); rv.NextUInt64().Is(13267978908934200754ul); rv.NextUInt64().Is(15679888225317814407ul); rv.NextUInt64().Is(14044878350692344958ul); rv.NextUInt64().Is(10760895422300929085ul); // NextULong only xo = new Xoshiro256StarStar(42); rv = new RandomVault(() => xo.NextUInt64(), null); DoubleToString(rv.NextDouble()).Is("0.0838629710598822"); DoubleToString(rv.NextDouble()).Is("0.3789802506626686"); DoubleToString(rv.NextDouble()).Is("0.6800434110281394"); DoubleToString(rv.NextDouble()).Is("0.9246929453253876"); DoubleToString(rv.NextDouble()).Is("0.9918039142821028"); rv.NextUInt64().Is(14199186830065750584ul); rv.NextUInt64().Is(13267978908934200754ul); rv.NextUInt64().Is(15679888225317814407ul); rv.NextUInt64().Is(14044878350692344958ul); rv.NextUInt64().Is(10760895422300929085ul); // NextBytes only xo = new Xoshiro256StarStar(42); rv = new RandomVault(null, x => xo.NextBytes(x)); DoubleToString(rv.NextDouble()).Is("0.0838629710598822"); DoubleToString(rv.NextDouble()).Is("0.3789802506626686"); DoubleToString(rv.NextDouble()).Is("0.6800434110281394"); DoubleToString(rv.NextDouble()).Is("0.9246929453253876"); DoubleToString(rv.NextDouble()).Is("0.9918039142821028"); rv.NextUInt64().Is(14199186830065750584ul); rv.NextUInt64().Is(13267978908934200754ul); rv.NextUInt64().Is(15679888225317814407ul); rv.NextUInt64().Is(14044878350692344958ul); rv.NextUInt64().Is(10760895422300929085ul); // Multi-thread var xo2 = new Xoshiro256StarStar(42); var rv2 = new RandomVault(() => xo2.NextUInt64(), x => xo2.NextBytes(x)); const int P = 100; const int N = 1000; var array = new Queue <ulong> [P]; var t = Parallel.For(0, P, x => { var queue = new Queue <ulong>(); for (var i = 0; i < N; i++) { queue.Enqueue(rv2.NextUInt64()); } array[x] = queue; }); var ss = new SortedSet <ulong>(); for (var i = 0; i < P; i++) { array[i].Count.Is(N); while (array[i].TryDequeue(out var u)) { ss.Contains(u).IsFalse(); ss.Add(u); } } ss.Count.Is(P * N); }