From 54ff0fc527bf479ab5ffe4483c0e5900a86ee5b1 Mon Sep 17 00:00:00 2001 From: godzzz Date: Tue, 18 Oct 2022 23:37:41 +0300 Subject: [PATCH] Improvements for performance; Cleaning --- .../ConcurrentPseudoRandomTests.cs | 14 +-- .../CryptoRandomTests.cs | 33 +++--- ...ndomTests.cs => PseudoRandomizersTests.cs} | 27 ++--- .../RandomServiceBuilderTests.cs | 3 + .../RandomizerExtensionsTests.Boolean.cs | 19 ++-- .../RandomizerExtensionsTests.Byte.cs | 5 +- .../RandomizerExtensionsTests.ByteArray.cs | 8 +- .../RandomizerExtensionsTests.CharArray.cs | 5 +- .../RandomizerExtensionsTests.Decimal.cs | 5 +- .../RandomizerExtensionsTests.Double.cs | 7 +- .../RandomizerExtensionsTests.Enums.cs | 5 +- .../RandomizerExtensionsTests.Float.cs | 5 +- .../RandomizerExtensionsTests.Int16.cs | 5 +- .../RandomizerExtensionsTests.Int32.cs | 5 +- .../RandomizerExtensionsTests.Int64.cs | 5 +- .../RandomizerExtensionsTests.SByte.cs | 5 +- .../RandomizerExtensionsTests.String.cs | 5 +- .../RandomizerExtensionsTests.UInt16.cs | 5 +- .../RandomizerExtensionsTests.UInt32.cs | 5 +- .../RandomizerExtensionsTests.UInt64.cs | 5 +- .../Boolean.RandomizerExtensionsBenchmarks.cs | 20 ++++ .../Byte.RandomizerExtensionsBenchmarks.cs | 23 ++++ ...yteArray.RandomizerExtensionsBenchmarks.cs | 23 ++++ ...harArray.RandomizerExtensionsBenchmarks.cs | 22 ++++ .../Decimal.RandomizerExtensionsBenchmarks.cs | 23 ++++ .../Double.RandomizerExtensionsBenchmarks.cs | 20 ++++ .../Int16.RandomizerExtensionsBenchmarks.cs | 23 ++++ .../Int64.RandomizerExtensionsBenchmarks.cs | 23 ++++ .../RandomizerExtensionsBenchmarks.Boolean.cs | 13 --- .../RandomizerExtensionsBenchmarks.Byte.cs | 21 ---- .../RandomizerExtensionsBenchmarks.Chars.cs | 16 --- .../RandomizerExtensionsBenchmarks.Decimal.cs | 16 --- .../RandomizerExtensionsBenchmarks.Float.cs | 16 --- .../RandomizerExtensionsBenchmarks.Int16.cs | 16 --- .../RandomizerExtensionsBenchmarks.Int64.cs | 17 --- .../RandomizerExtensionsBenchmarks.SByte.cs | 16 --- .../RandomizerExtensionsBenchmarks.String.cs | 15 --- .../RandomizerExtensionsBenchmarks.UInt16.cs | 16 --- .../RandomizerExtensionsBenchmarks.UInt32.cs | 16 --- .../RandomizerExtensionsBenchmarks.UInt64.cs | 16 --- .../RandomizerExtensionsBenchmarks.cs | 20 ---- .../SByte.RandomizerExtensionsBenchmarks.cs | 23 ++++ .../Single.RandomizerExtensionsBenchmarks.cs | 23 ++++ .../String.RandomizerExtensionsBenchmarks.cs | 23 ++++ .../UInt16.RandomizerExtensionsBenchmarks.cs | 23 ++++ .../UInt32.RandomizerExtensionsBenchmarks.cs | 23 ++++ .../UInt64.RandomizerExtensionsBenchmarks.cs | 23 ++++ Random.Benchmarks/Program.cs | 4 +- .../Randomizers/ConcurrentRandomBenchmarks.cs | 24 ++--- .../Randomizers/CryptoRandomBenchmarks.cs | 26 +++-- .../Service/RandomServiceBenchmarks.cs | 31 +++--- .../Application/Extensions/ArrayExtensions.cs | 2 +- .../Extensions/EnumerableExtensions.cs | 2 +- .../Application/Extensions/ListExtensions.cs | 2 +- .../RandomizerCollectionExtensions.cs | 19 ++++ .../ServiceBuilder/IRandomServiceBuilder.cs | 3 + .../ServiceBuilder/RandomServiceBuilder.cs | 4 +- .../RandomServiceBuilderExtensions.cs | 17 +-- .../Services/RandomServiceExtensions.cs | 3 + .../ConcurrentPseudoRandomizers.cs | 36 +++++++ .../System/Collections/CryptoRandomizers.cs | 30 ++++++ .../System/Collections/PseudoRandomizers.cs | 32 ++++++ .../System/ConcurrentPseudoRandom.cs | 101 ------------------ .../System/Mapping/SystemRandomizersMapper.cs | 53 +++++++++ .../System/Proxy/ByteArrayRandomProxy.cs | 21 ++++ .../System/Proxy/DoubleRandomProxy.cs | 21 ++++ .../System/Proxy/IntRandomProxy.cs | 27 +++++ .../System/Proxy/SystemRandomProxy.cs | 17 +++ Random/Application/System/PseudoRandom.cs | 36 ------- .../System/Randoms/ConcurrentPseudoRandom.cs | 70 ++++++++++++ .../CryptoRandom.cs} | 52 +++++---- ...RandomizerForTypeNotRegisteredException.cs | 3 + .../Domain/Exceptions/ThrowHelper.Partial.cs | 3 + Random/Domain/Exceptions/ThrowHelper.cs | 1 - .../Extensions/RandomizerExtensions.Int64.cs | 1 - Random/Domain/Randomizers/IArrayRandomizer.cs | 3 + .../Domain/Randomizers/INumberRandomizer.cs | 3 + Random/Domain/Randomizers/IRandomizer.cs | 6 +- .../Randomizers/IRandomizerCollection.cs | 3 + Random/Domain/Randomizers/ITypedRandomizer.cs | 3 + 80 files changed, 860 insertions(+), 504 deletions(-) rename Random.Application.UnitTests/{PseudoRandomTests.cs => PseudoRandomizersTests.cs} (78%) create mode 100644 Random.Benchmarks/Extensions/Boolean.RandomizerExtensionsBenchmarks.cs create mode 100644 Random.Benchmarks/Extensions/Byte.RandomizerExtensionsBenchmarks.cs create mode 100644 Random.Benchmarks/Extensions/ByteArray.RandomizerExtensionsBenchmarks.cs create mode 100644 Random.Benchmarks/Extensions/CharArray.RandomizerExtensionsBenchmarks.cs create mode 100644 Random.Benchmarks/Extensions/Decimal.RandomizerExtensionsBenchmarks.cs create mode 100644 Random.Benchmarks/Extensions/Double.RandomizerExtensionsBenchmarks.cs create mode 100644 Random.Benchmarks/Extensions/Int16.RandomizerExtensionsBenchmarks.cs create mode 100644 Random.Benchmarks/Extensions/Int64.RandomizerExtensionsBenchmarks.cs delete mode 100644 Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Boolean.cs delete mode 100644 Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Byte.cs delete mode 100644 Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Chars.cs delete mode 100644 Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Decimal.cs delete mode 100644 Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Float.cs delete mode 100644 Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Int16.cs delete mode 100644 Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Int64.cs delete mode 100644 Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.SByte.cs delete mode 100644 Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.String.cs delete mode 100644 Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.UInt16.cs delete mode 100644 Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.UInt32.cs delete mode 100644 Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.UInt64.cs delete mode 100644 Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.cs create mode 100644 Random.Benchmarks/Extensions/SByte.RandomizerExtensionsBenchmarks.cs create mode 100644 Random.Benchmarks/Extensions/Single.RandomizerExtensionsBenchmarks.cs create mode 100644 Random.Benchmarks/Extensions/String.RandomizerExtensionsBenchmarks.cs create mode 100644 Random.Benchmarks/Extensions/UInt16.RandomizerExtensionsBenchmarks.cs create mode 100644 Random.Benchmarks/Extensions/UInt32.RandomizerExtensionsBenchmarks.cs create mode 100644 Random.Benchmarks/Extensions/UInt64.RandomizerExtensionsBenchmarks.cs create mode 100644 Random/Application/Extensions/RandomizerCollectionExtensions.cs create mode 100644 Random/Application/System/Collections/ConcurrentPseudoRandomizers.cs create mode 100644 Random/Application/System/Collections/CryptoRandomizers.cs create mode 100644 Random/Application/System/Collections/PseudoRandomizers.cs delete mode 100644 Random/Application/System/ConcurrentPseudoRandom.cs create mode 100644 Random/Application/System/Mapping/SystemRandomizersMapper.cs create mode 100644 Random/Application/System/Proxy/ByteArrayRandomProxy.cs create mode 100644 Random/Application/System/Proxy/DoubleRandomProxy.cs create mode 100644 Random/Application/System/Proxy/IntRandomProxy.cs create mode 100644 Random/Application/System/Proxy/SystemRandomProxy.cs delete mode 100644 Random/Application/System/PseudoRandom.cs create mode 100644 Random/Application/System/Randoms/ConcurrentPseudoRandom.cs rename Random/Application/System/{CryptoRandomizer.cs => Randoms/CryptoRandom.cs} (63%) diff --git a/Random.Application.UnitTests/ConcurrentPseudoRandomTests.cs b/Random.Application.UnitTests/ConcurrentPseudoRandomTests.cs index c19e643..14e8869 100644 --- a/Random.Application.UnitTests/ConcurrentPseudoRandomTests.cs +++ b/Random.Application.UnitTests/ConcurrentPseudoRandomTests.cs @@ -2,12 +2,12 @@ // SPDX-License-Identifier: Apache-2.0 using System.Collections; -using Depra.Random.Application.System; -using Depra.Random.Domain.Randomizers; +using Depra.Random.Application.System.Collections; +using Depra.Random.Application.System.Randoms; namespace Depra.Random.Application.UnitTests; -[TestFixture(TestOf = typeof(ConcurrentPseudoRandom))] +[TestFixture(TestOf = typeof(ConcurrentPseudoRandomizers))] internal class ConcurrentPseudoRandomTests { private ConcurrentPseudoRandom _concurrentPseudoRandom = null!; @@ -76,7 +76,7 @@ public void WhenGettingNextDoubleParallel_AndRangeIsDefault_ThenZerosNotFound( [Values(10_000)] int samplesCount) { // Arrange. - ITypedRandomizer randomizer = _concurrentPseudoRandom; + var randomizer = _concurrentPseudoRandom; var allThreadIssues = 0; // Act. @@ -85,7 +85,7 @@ public void WhenGettingNextDoubleParallel_AndRangeIsDefault_ThenZerosNotFound( var randomNumbers = new double[samplesCount]; for (var i = 0; i < samplesCount; i++) { - randomNumbers[i] = randomizer.Next(); + randomNumbers[i] = randomizer.NextDouble(); } var threadIssues = randomNumbers.Count(x => x == 0); @@ -104,7 +104,7 @@ public void WhenGettingNextBytesParallel_AndBufferLength8_ThenZerosNotFound( { // Arrange. const int bufferLength = 8; - IArrayRandomizer randomizer = _concurrentPseudoRandom; + var randomizer = _concurrentPseudoRandom; var sourceBuffer = new byte[bufferLength]; var allThreadIssues = 0; @@ -115,7 +115,7 @@ public void WhenGettingNextBytesParallel_AndBufferLength8_ThenZerosNotFound( for (var i = 0; i < samplesCount; i++) { var bufferCopy = sourceBuffer.ToArray(); - randomizer.Next(bufferCopy); + randomizer.NextBytes(bufferCopy); results.Add(bufferCopy); } diff --git a/Random.Application.UnitTests/CryptoRandomTests.cs b/Random.Application.UnitTests/CryptoRandomTests.cs index e45ccfa..0657b8b 100644 --- a/Random.Application.UnitTests/CryptoRandomTests.cs +++ b/Random.Application.UnitTests/CryptoRandomTests.cs @@ -2,29 +2,28 @@ // SPDX-License-Identifier: Apache-2.0 using System.Collections; -using Depra.Random.Application.System; +using Depra.Random.Application.System.Randoms; using Depra.Random.Application.UnitTests.Helpers; -using Depra.Random.Domain.Randomizers; namespace Depra.Random.Application.UnitTests; -[TestFixture(TestOf = typeof(CryptoRandomizer))] +[TestFixture(TestOf = typeof(CryptoRandom))] internal class CryptoRandomTests { - private CryptoRandomizer _cryptoRandomizer = null!; + private CryptoRandom _cryptoRandom = null!; [SetUp] - public void SetUp() => _cryptoRandomizer = new CryptoRandomizer(); + public void SetUp() => _cryptoRandom = new CryptoRandom(); [TearDown] - public void TearDown() => _cryptoRandomizer.Dispose(); + public void TearDown() => _cryptoRandom.Dispose(); [Test] public void WhenGettingNextInt32_AndRangeIsDefault_ThenRandomNumbersAreUnique( [Values(10_000)] int samplesCount) { // Arrange. - var randomizer = _cryptoRandomizer; + var randomizer = _cryptoRandom; var randomNumbers = new int[samplesCount]; // Act. @@ -46,7 +45,7 @@ public void WhenGettingNextInt32_AndInRangeWithMinAndMax_ThenRandomNumbersAreUni // Arrange. const int minValue = int.MinValue; const int maxValue = int.MaxValue; - var randomizer = _cryptoRandomizer; + var randomizer = _cryptoRandom; var randomNumbers = new int[samplesCount]; // Act. @@ -66,13 +65,13 @@ public void WhenGettingNextDouble_AndRangeIsDefault_ThenRandomNumbersAreUnique( [Values(10_000)] int samplesCount) { // Arrange. - ITypedRandomizer randomizer = _cryptoRandomizer; + var randomizer = _cryptoRandom; var randomNumbers = new double[samplesCount]; // Act. for (var i = 0; i < samplesCount; i++) { - randomNumbers[i] = randomizer.Next(); + randomNumbers[i] = randomizer.NextDouble(); } ConsoleHelper.PrintCollection(randomNumbers); @@ -87,14 +86,14 @@ public void WhenGettingNextBytes_AndBufferLength8_ThenRandomByteArraysAreUnique( { // Arrange. const int bufferLength = 8; - IArrayRandomizer randomizer = _cryptoRandomizer; + var randomizer = _cryptoRandom; var bytesStack = new Stack(); // Act. for (var i = 0; i < samplesCount; i++) { var buffer = new byte[bufferLength]; - randomizer.Next(buffer); + randomizer.NextBytes(buffer); bytesStack.Push(buffer); ConsoleHelper.PrintBytes(buffer); @@ -111,7 +110,7 @@ public void WhenGettingNextInt32Parallel_AndInRangeWithMinAndMax_ThenZerosNotFou // Arrange. const int minValue = int.MinValue; const int maxValue = int.MaxValue; - var randomizer = _cryptoRandomizer; + var randomizer = _cryptoRandom; var allThreadIssues = 0; // Act. @@ -138,7 +137,7 @@ public void WhenGettingNextDoubleParallel_AndRangeIsDefault_ThenZerosNotFound( [Values(10_000)] int samplesCount) { // Arrange. - ITypedRandomizer randomizer = _cryptoRandomizer; + var randomizer = _cryptoRandom; var allThreadIssues = 0; // Act. @@ -147,7 +146,7 @@ public void WhenGettingNextDoubleParallel_AndRangeIsDefault_ThenZerosNotFound( var numbers = new double[samplesCount]; for (var i = 0; i < samplesCount; i++) { - numbers[i] = randomizer.Next(); + numbers[i] = randomizer.NextDouble(); } var threadIssues = numbers.Count(x => x == 0); @@ -166,7 +165,7 @@ public void WhenGettingNextBytesParallel_AndBufferLength8_ThenZerosNotFound( { // Arrange. const int bufferLength = 8; - IArrayRandomizer randomizer = _cryptoRandomizer; + var randomizer = _cryptoRandom; var sourceBuffer = new byte[bufferLength]; var allThreadIssues = 0; @@ -177,7 +176,7 @@ public void WhenGettingNextBytesParallel_AndBufferLength8_ThenZerosNotFound( for (var i = 0; i < samplesCount; i++) { var bufferCopy = sourceBuffer.ToArray(); - randomizer.Next(bufferCopy); + randomizer.NextBytes(bufferCopy); results.Add(bufferCopy); } diff --git a/Random.Application.UnitTests/PseudoRandomTests.cs b/Random.Application.UnitTests/PseudoRandomizersTests.cs similarity index 78% rename from Random.Application.UnitTests/PseudoRandomTests.cs rename to Random.Application.UnitTests/PseudoRandomizersTests.cs index 5764876..6c52b3e 100644 --- a/Random.Application.UnitTests/PseudoRandomTests.cs +++ b/Random.Application.UnitTests/PseudoRandomizersTests.cs @@ -1,26 +1,28 @@ // Copyright © 2022 Nikolay Melnikov. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -using Depra.Random.Application.System; +using Depra.Random.Application.Extensions; +using Depra.Random.Application.System.Collections; using Depra.Random.Application.UnitTests.Helpers; +using Depra.Random.Domain.Extensions; namespace Depra.Random.Application.UnitTests; -[TestFixture] -internal class PseudoRandomTests +[TestFixture(TestOf = typeof(PseudoRandomizers))] +internal class PseudoRandomizersTests { - private PseudoRandom _pseudoRandom = null!; + private PseudoRandomizers _pseudoRandomizers = null!; [SetUp] - public void SetUp() => _pseudoRandom = new PseudoRandom(); + public void SetUp() => _pseudoRandomizers = new PseudoRandomizers(); [Test] public void WhenGettingNextInt32_AndRangeIsDefault_ThenRandomNumbersAreNotTheSame( [Values(10)] int samplesCount) { // Arrange. - var randomizer = _pseudoRandom; var randomNumbers = new int[samplesCount]; + var randomizer = _pseudoRandomizers.GetNumberRandomizer(); // Act. for (var i = 0; i < samplesCount; i++) @@ -41,8 +43,8 @@ public void WhenGettingNextInt32_AndInRangeWithMin_ThenRandomNumbersAreInGivenRa // Arrange. const int minValue = 0; const int maxValue = int.MaxValue; - var randomizer = _pseudoRandom; var randomNumbers = new int[samplesCount]; + var randomizer = _pseudoRandomizers.GetNumberRandomizer(); // Act. for (var i = 0; i < samplesCount; i++) @@ -63,8 +65,8 @@ public void WhenGettingNextInt32_AndInRangeWithMinAndMax_ThenRandomNumbersAreInG // Arrange. const int minValue = int.MinValue; const int maxValue = int.MaxValue; - var randomizer = _pseudoRandom; var randomNumbers = new int[samplesCount]; + var randomizer = _pseudoRandomizers.GetNumberRandomizer(); // Act. for (var i = 0; i < samplesCount; i++) @@ -85,8 +87,8 @@ public void WhenGettingNextDouble_AndInDefaultRange_ThenRandomNumbersAreNotTheSa { // Arrange. const double tolerance = 0.01; - var randomizer = _pseudoRandom; var randomNumbers = new double[samplesCount]; + var randomizer = _pseudoRandomizers.GetTypedRandomizer(); // Act. for (var i = 0; i < samplesCount; i++) @@ -104,11 +106,12 @@ public void WhenGettingNextDouble_AndInDefaultRange_ThenRandomNumbersAreNotTheSa public void WhenGettingNextByteArray_AndBufferWithLenght64_ThenBufferIsNotNullOrEmpty() { // Arrange. - var randomizer = _pseudoRandom; - var buffer = new byte[64]; + const int bufferLenght = 64; + var buffer = new byte[bufferLenght]; + var randomizer = _pseudoRandomizers.GetArrayRandomizer(); // Act. - randomizer.NextBytes(buffer); + randomizer.Next(buffer); ConsoleHelper.PrintBytes(buffer); // Assert. diff --git a/Random.Application.UnitTests/RandomServiceBuilderTests.cs b/Random.Application.UnitTests/RandomServiceBuilderTests.cs index 12e09d0..ff5974e 100644 --- a/Random.Application.UnitTests/RandomServiceBuilderTests.cs +++ b/Random.Application.UnitTests/RandomServiceBuilderTests.cs @@ -1,3 +1,6 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + using Depra.Random.Application.ServiceBuilder; using Depra.Random.Domain.Exceptions; using Depra.Random.Domain.Randomizers; diff --git a/Random.Application.UnitTests/RandomizerExtensionsTests.Boolean.cs b/Random.Application.UnitTests/RandomizerExtensionsTests.Boolean.cs index b78e8a4..a224e0a 100644 --- a/Random.Application.UnitTests/RandomizerExtensionsTests.Boolean.cs +++ b/Random.Application.UnitTests/RandomizerExtensionsTests.Boolean.cs @@ -1,7 +1,8 @@ // Copyright © 2022 Nikolay Melnikov. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -using Depra.Random.Application.System; +using Depra.Random.Application.Extensions; +using Depra.Random.Application.System.Collections; using Depra.Random.Domain.Extensions; using Depra.Random.Domain.Randomizers; @@ -12,17 +13,23 @@ internal static partial class RandomizerExtensionsTests [TestFixture] internal class Boolean { - private PseudoRandom _randomizer = null!; + private INumberRandomizer _intRandomizer = null!; + private ITypedRandomizer _doubleRandomizer = null!; [SetUp] - public void SetUp() => _randomizer = new PseudoRandom(); + public void SetUp() + { + var randomizers = new PseudoRandomizers(); + _intRandomizer = randomizers.GetNumberRandomizer(); + _doubleRandomizer = randomizers.GetTypedRandomizer(); + } [Test] public void WhenGettingNextBooleans_AndProbabilityIsDefault_ThenRandomBooleansAreNotTheSame( [Values(100)] int samplesCount) { // Arrange. - INumberRandomizer randomizer = _randomizer; + var randomizer = _intRandomizer; var randomBooleans = new bool[samplesCount]; // Act. @@ -41,7 +48,7 @@ public void WhenGettingNextBoolean_AndProbabilityIsOne_ThenRandomBooleansAreAlwa { // Arrange. const int probability = 1; - ITypedRandomizer randomizer = _randomizer; + var randomizer = _doubleRandomizer; var randomBooleans = new bool[samplesCount]; // Act. @@ -60,7 +67,7 @@ public void WhenGettingNextBoolean_AndProbabilityIsZero_ThenRandomBooleansAreAlw { // Arrange. const int probability = 0; - ITypedRandomizer randomizer = _randomizer; + var randomizer = _doubleRandomizer; var randomBooleans = new bool[samplesCount]; // Act. diff --git a/Random.Application.UnitTests/RandomizerExtensionsTests.Byte.cs b/Random.Application.UnitTests/RandomizerExtensionsTests.Byte.cs index e5073a3..223cbe7 100644 --- a/Random.Application.UnitTests/RandomizerExtensionsTests.Byte.cs +++ b/Random.Application.UnitTests/RandomizerExtensionsTests.Byte.cs @@ -1,7 +1,8 @@ // Copyright © 2022 Nikolay Melnikov. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -using Depra.Random.Application.System; +using Depra.Random.Application.Extensions; +using Depra.Random.Application.System.Collections; using Depra.Random.Application.UnitTests.Helpers; using Depra.Random.Domain.Extensions; using Depra.Random.Domain.Randomizers; @@ -16,7 +17,7 @@ internal class Byte private INumberRandomizer _randomizer = null!; [SetUp] - public void SetUp() => _randomizer = new PseudoRandom(); + public void SetUp() => _randomizer = new PseudoRandomizers().GetNumberRandomizer(); [Test] public void WhenGettingNextByte_AndInRangeWithMax_ThenRandomBytesAreInGivenRange( diff --git a/Random.Application.UnitTests/RandomizerExtensionsTests.ByteArray.cs b/Random.Application.UnitTests/RandomizerExtensionsTests.ByteArray.cs index e00ec76..1ade98b 100644 --- a/Random.Application.UnitTests/RandomizerExtensionsTests.ByteArray.cs +++ b/Random.Application.UnitTests/RandomizerExtensionsTests.ByteArray.cs @@ -1,4 +1,8 @@ -using Depra.Random.Application.System; +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using Depra.Random.Application.Extensions; +using Depra.Random.Application.System.Collections; using Depra.Random.Application.UnitTests.Helpers; using Depra.Random.Domain.Extensions; using Depra.Random.Domain.Randomizers; @@ -13,7 +17,7 @@ internal class ByteArray private IArrayRandomizer _randomizer = null!; [SetUp] - public void SetUp() => _randomizer = new PseudoRandom(); + public void SetUp() => _randomizer = new PseudoRandomizers().GetArrayRandomizer(); [Test] public void WhenGettingNextByteArray_ThenResultingArrayLengthIsEqualInitial( diff --git a/Random.Application.UnitTests/RandomizerExtensionsTests.CharArray.cs b/Random.Application.UnitTests/RandomizerExtensionsTests.CharArray.cs index 0c56768..92209cf 100644 --- a/Random.Application.UnitTests/RandomizerExtensionsTests.CharArray.cs +++ b/Random.Application.UnitTests/RandomizerExtensionsTests.CharArray.cs @@ -1,7 +1,8 @@ // Copyright © 2022 Nikolay Melnikov. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -using Depra.Random.Application.System; +using Depra.Random.Application.Extensions; +using Depra.Random.Application.System.Collections; using Depra.Random.Application.UnitTests.Helpers; using Depra.Random.Domain.Extensions; using Depra.Random.Domain.Randomizers; @@ -16,7 +17,7 @@ internal class CharArray private INumberRandomizer _randomizer = null!; [SetUp] - public void SetUp() => _randomizer = new PseudoRandom(); + public void SetUp() => _randomizer = new PseudoRandomizers().GetNumberRandomizer(); [Test] public void WhenGettingNextChars_AndUsingBuffer_ThenRandomCharArrayIsNotNullOrEmpty( diff --git a/Random.Application.UnitTests/RandomizerExtensionsTests.Decimal.cs b/Random.Application.UnitTests/RandomizerExtensionsTests.Decimal.cs index dd3faa1..36b29c0 100644 --- a/Random.Application.UnitTests/RandomizerExtensionsTests.Decimal.cs +++ b/Random.Application.UnitTests/RandomizerExtensionsTests.Decimal.cs @@ -1,7 +1,8 @@ // Copyright © 2022 Nikolay Melnikov. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -using Depra.Random.Application.System; +using Depra.Random.Application.Extensions; +using Depra.Random.Application.System.Collections; using Depra.Random.Application.UnitTests.Helpers; using Depra.Random.Domain.Extensions; using Depra.Random.Domain.Randomizers; @@ -16,7 +17,7 @@ internal class Decimal private INumberRandomizer _randomizer = null!; [SetUp] - public void SetUp() => _randomizer = new PseudoRandom(); + public void SetUp() => _randomizer = new PseudoRandomizers().GetNumberRandomizer(); [Test] public void WhenGettingNextDecimal_AndRangeIsDefault_ThenRandomNumbersAreNotTheSame() diff --git a/Random.Application.UnitTests/RandomizerExtensionsTests.Double.cs b/Random.Application.UnitTests/RandomizerExtensionsTests.Double.cs index fa189e5..f1a0b2f 100644 --- a/Random.Application.UnitTests/RandomizerExtensionsTests.Double.cs +++ b/Random.Application.UnitTests/RandomizerExtensionsTests.Double.cs @@ -1,7 +1,8 @@ // Copyright © 2022 Nikolay Melnikov. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -using Depra.Random.Application.System; +using Depra.Random.Application.Extensions; +using Depra.Random.Application.System.Collections; using Depra.Random.Application.UnitTests.Helpers; using Depra.Random.Domain.Extensions; using Depra.Random.Domain.Randomizers; @@ -16,7 +17,7 @@ internal class Double private ITypedRandomizer _randomizer = null!; [SetUp] - public void SetUp() => _randomizer = new PseudoRandom(); + public void SetUp() => _randomizer = new PseudoRandomizers().GetTypedRandomizer(); [Test] public void WhenGettingNextDouble_AndRangeIsDefault_ThenRandomNumbersAreNotTheSame( @@ -40,7 +41,7 @@ public void WhenGettingNextDouble_AndRangeIsDefault_ThenRandomNumbersAreNotTheSa } [Test] - public void WhenGettingNextDouble_AndInRangeWithMinAndMax_ThenRandomNubmersAreInGivenRange( + public void WhenGettingNextDouble_AndInRangeWithMinAndMax_ThenRandomNumbersAreInGivenRange( [Values(100)] int samplesCount) { // Arrange. diff --git a/Random.Application.UnitTests/RandomizerExtensionsTests.Enums.cs b/Random.Application.UnitTests/RandomizerExtensionsTests.Enums.cs index 9d978f6..08785d2 100644 --- a/Random.Application.UnitTests/RandomizerExtensionsTests.Enums.cs +++ b/Random.Application.UnitTests/RandomizerExtensionsTests.Enums.cs @@ -1,7 +1,8 @@ // Copyright © 2022 Nikolay Melnikov. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -using Depra.Random.Application.System; +using Depra.Random.Application.Extensions; +using Depra.Random.Application.System.Collections; using Depra.Random.Domain.Extensions; using Depra.Random.Domain.Randomizers; @@ -15,7 +16,7 @@ internal class Enums private INumberRandomizer _randomizer = null!; [SetUp] - public void SetUp() => _randomizer = new PseudoRandom(); + public void SetUp() => _randomizer = new PseudoRandomizers().GetNumberRandomizer(); [Test] public void WhenGettingNextEnum_AndEnumTypeIsTestEnum_ThenRandomEnumIsDefined() diff --git a/Random.Application.UnitTests/RandomizerExtensionsTests.Float.cs b/Random.Application.UnitTests/RandomizerExtensionsTests.Float.cs index ebc0a59..3c465d0 100644 --- a/Random.Application.UnitTests/RandomizerExtensionsTests.Float.cs +++ b/Random.Application.UnitTests/RandomizerExtensionsTests.Float.cs @@ -1,7 +1,8 @@ // Copyright © 2022 Nikolay Melnikov. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -using Depra.Random.Application.System; +using Depra.Random.Application.Extensions; +using Depra.Random.Application.System.Collections; using Depra.Random.Application.UnitTests.Helpers; using Depra.Random.Domain.Extensions; using Depra.Random.Domain.Randomizers; @@ -16,7 +17,7 @@ internal class Float private ITypedRandomizer _randomizer = null!; [SetUp] - public void SetUp() => _randomizer = new PseudoRandom(); + public void SetUp() => _randomizer = new PseudoRandomizers().GetTypedRandomizer(); [Test] public void WhenGettingNextFloat_AndRangeIsDefault_ThenRandomNumbersAreNotTheSame( diff --git a/Random.Application.UnitTests/RandomizerExtensionsTests.Int16.cs b/Random.Application.UnitTests/RandomizerExtensionsTests.Int16.cs index edc696a..2eeda24 100644 --- a/Random.Application.UnitTests/RandomizerExtensionsTests.Int16.cs +++ b/Random.Application.UnitTests/RandomizerExtensionsTests.Int16.cs @@ -1,7 +1,8 @@ // Copyright © 2022 Nikolay Melnikov. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -using Depra.Random.Application.System; +using Depra.Random.Application.Extensions; +using Depra.Random.Application.System.Collections; using Depra.Random.Application.UnitTests.Helpers; using Depra.Random.Domain.Extensions; using Depra.Random.Domain.Randomizers; @@ -16,7 +17,7 @@ internal class Int16 private INumberRandomizer _randomizer = null!; [SetUp] - public void SetUp() => _randomizer = new PseudoRandom(); + public void SetUp() => _randomizer = new PseudoRandomizers().GetNumberRandomizer(); [Test] public void WhenGettingNextInt16_AndRangeIsDefault_ThenRandomNumbersAreNotTheSame( diff --git a/Random.Application.UnitTests/RandomizerExtensionsTests.Int32.cs b/Random.Application.UnitTests/RandomizerExtensionsTests.Int32.cs index 8fc5c9b..dddf4bd 100644 --- a/Random.Application.UnitTests/RandomizerExtensionsTests.Int32.cs +++ b/Random.Application.UnitTests/RandomizerExtensionsTests.Int32.cs @@ -1,7 +1,8 @@ // Copyright © 2022 Nikolay Melnikov. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -using Depra.Random.Application.System; +using Depra.Random.Application.Extensions; +using Depra.Random.Application.System.Collections; using Depra.Random.Application.UnitTests.Helpers; using Depra.Random.Domain.Extensions; using Depra.Random.Domain.Randomizers; @@ -16,7 +17,7 @@ internal class Int32 private INumberRandomizer _randomizer = null!; [SetUp] - public void SetUp() => _randomizer = new PseudoRandom(); + public void SetUp() => _randomizer = new PseudoRandomizers().GetNumberRandomizer(); [Test] public void WhenGettingNextInt32_AndInPositiveRange_ThenRandomNumbersArePositive( diff --git a/Random.Application.UnitTests/RandomizerExtensionsTests.Int64.cs b/Random.Application.UnitTests/RandomizerExtensionsTests.Int64.cs index 5e0270c..8654a48 100644 --- a/Random.Application.UnitTests/RandomizerExtensionsTests.Int64.cs +++ b/Random.Application.UnitTests/RandomizerExtensionsTests.Int64.cs @@ -1,7 +1,8 @@ // Copyright © 2022 Nikolay Melnikov. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -using Depra.Random.Application.System; +using Depra.Random.Application.Extensions; +using Depra.Random.Application.System.Collections; using Depra.Random.Application.UnitTests.Helpers; using Depra.Random.Domain.Extensions; using Depra.Random.Domain.Randomizers; @@ -16,7 +17,7 @@ internal class Int64 private IArrayRandomizer _randomizer = null!; [SetUp] - public void SetUp() => _randomizer = new PseudoRandom(); + public void SetUp() => _randomizer = new PseudoRandomizers().GetArrayRandomizer(); [Test] public void WhenGettingNextInt64_AndRangeIsDefault_ThenRandomNumbersAreNotTheSame( diff --git a/Random.Application.UnitTests/RandomizerExtensionsTests.SByte.cs b/Random.Application.UnitTests/RandomizerExtensionsTests.SByte.cs index 56f4f06..4d112f2 100644 --- a/Random.Application.UnitTests/RandomizerExtensionsTests.SByte.cs +++ b/Random.Application.UnitTests/RandomizerExtensionsTests.SByte.cs @@ -1,7 +1,8 @@ // Copyright © 2022 Nikolay Melnikov. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -using Depra.Random.Application.System; +using Depra.Random.Application.Extensions; +using Depra.Random.Application.System.Collections; using Depra.Random.Application.UnitTests.Helpers; using Depra.Random.Domain.Extensions; using Depra.Random.Domain.Randomizers; @@ -16,7 +17,7 @@ internal class SByte private INumberRandomizer _randomizer = null!; [SetUp] - public void SetUp() => _randomizer = new PseudoRandom(); + public void SetUp() => _randomizer = new PseudoRandomizers().GetNumberRandomizer(); [Test] public void WhenGettingNextSByte_AndRangeIsDefault_ThenRandomBytesAreNotTheSame( diff --git a/Random.Application.UnitTests/RandomizerExtensionsTests.String.cs b/Random.Application.UnitTests/RandomizerExtensionsTests.String.cs index 0a3c1bb..8d8ae61 100644 --- a/Random.Application.UnitTests/RandomizerExtensionsTests.String.cs +++ b/Random.Application.UnitTests/RandomizerExtensionsTests.String.cs @@ -1,7 +1,8 @@ // Copyright © 2022 Nikolay Melnikov. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -using Depra.Random.Application.System; +using Depra.Random.Application.Extensions; +using Depra.Random.Application.System.Collections; using Depra.Random.Domain.Extensions; using Depra.Random.Domain.Randomizers; @@ -15,7 +16,7 @@ internal class String private INumberRandomizer _randomizer = null!; [SetUp] - public void SetUp() => _randomizer = new PseudoRandom(); + public void SetUp() => _randomizer = new PseudoRandomizers().GetNumberRandomizer(); [Test] public void WhenGettingNextString_AndNotIncludeLowerCase_ThenRandomStringIsNotInLowerCase( diff --git a/Random.Application.UnitTests/RandomizerExtensionsTests.UInt16.cs b/Random.Application.UnitTests/RandomizerExtensionsTests.UInt16.cs index 348b00d..5885056 100644 --- a/Random.Application.UnitTests/RandomizerExtensionsTests.UInt16.cs +++ b/Random.Application.UnitTests/RandomizerExtensionsTests.UInt16.cs @@ -1,7 +1,8 @@ // Copyright © 2022 Nikolay Melnikov. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -using Depra.Random.Application.System; +using Depra.Random.Application.Extensions; +using Depra.Random.Application.System.Collections; using Depra.Random.Application.UnitTests.Helpers; using Depra.Random.Domain.Extensions; using Depra.Random.Domain.Randomizers; @@ -16,7 +17,7 @@ internal class UInt16 private INumberRandomizer _randomizer = null!; [SetUp] - public void SetUp() => _randomizer = new PseudoRandom(); + public void SetUp() => _randomizer = new PseudoRandomizers().GetNumberRandomizer(); [Test] public void WhenGettingNextUInt16_AndRangeIsDefault_ThenRandomNumbersAreNotTheSame( diff --git a/Random.Application.UnitTests/RandomizerExtensionsTests.UInt32.cs b/Random.Application.UnitTests/RandomizerExtensionsTests.UInt32.cs index ca99970..d8eaa3a 100644 --- a/Random.Application.UnitTests/RandomizerExtensionsTests.UInt32.cs +++ b/Random.Application.UnitTests/RandomizerExtensionsTests.UInt32.cs @@ -1,7 +1,8 @@ // Copyright © 2022 Nikolay Melnikov. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -using Depra.Random.Application.System; +using Depra.Random.Application.Extensions; +using Depra.Random.Application.System.Collections; using Depra.Random.Application.UnitTests.Helpers; using Depra.Random.Domain.Extensions; using Depra.Random.Domain.Randomizers; @@ -16,7 +17,7 @@ internal class UInt32 private INumberRandomizer _randomizer = null!; [SetUp] - public void SetUp() => _randomizer = new PseudoRandom(); + public void SetUp() => _randomizer = new PseudoRandomizers().GetNumberRandomizer(); [Test] public void WhenGettingNextUInt32_AndRangeIsDefault_ThenRandomNumbersAreNotTheSame( diff --git a/Random.Application.UnitTests/RandomizerExtensionsTests.UInt64.cs b/Random.Application.UnitTests/RandomizerExtensionsTests.UInt64.cs index 62d9420..b6c5d14 100644 --- a/Random.Application.UnitTests/RandomizerExtensionsTests.UInt64.cs +++ b/Random.Application.UnitTests/RandomizerExtensionsTests.UInt64.cs @@ -1,7 +1,8 @@ // Copyright © 2022 Nikolay Melnikov. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -using Depra.Random.Application.System; +using Depra.Random.Application.Extensions; +using Depra.Random.Application.System.Collections; using Depra.Random.Application.UnitTests.Helpers; using Depra.Random.Domain.Extensions; using Depra.Random.Domain.Randomizers; @@ -16,7 +17,7 @@ internal class UInt64 private IArrayRandomizer _randomizer = null!; [SetUp] - public void SetUp() => _randomizer = new PseudoRandom(); + public void SetUp() => _randomizer = new PseudoRandomizers().GetArrayRandomizer(); [Test] public void WhenGettingNextUInt64_AndNumberOfSamplesIs100_ThenRandomNumbersAreNotTheSame( diff --git a/Random.Benchmarks/Extensions/Boolean.RandomizerExtensionsBenchmarks.cs b/Random.Benchmarks/Extensions/Boolean.RandomizerExtensionsBenchmarks.cs new file mode 100644 index 0000000..a8de71a --- /dev/null +++ b/Random.Benchmarks/Extensions/Boolean.RandomizerExtensionsBenchmarks.cs @@ -0,0 +1,20 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Attributes; +using Depra.Random.Application.System.Collections; +using Depra.Random.Domain.Extensions; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Benchmarks.Extensions; + +public class BooleanRandomizerExtensionsBenchmarks +{ + private INumberRandomizer _doubleRandomizer; + + [GlobalSetup] + public void Setup() => _doubleRandomizer = new PseudoRandomizers().GetNumberRandomizer(); + + [Benchmark] + public bool NextBool() => _doubleRandomizer.NextBoolean(); +} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/Byte.RandomizerExtensionsBenchmarks.cs b/Random.Benchmarks/Extensions/Byte.RandomizerExtensionsBenchmarks.cs new file mode 100644 index 0000000..8dbc551 --- /dev/null +++ b/Random.Benchmarks/Extensions/Byte.RandomizerExtensionsBenchmarks.cs @@ -0,0 +1,23 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Attributes; +using Depra.Random.Application.System.Collections; +using Depra.Random.Domain.Extensions; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Benchmarks.Extensions; + +public class ByteRandomizerExtensionsBenchmarks +{ + private INumberRandomizer _intRandomizer; + + [GlobalSetup] + public void Setup() => _intRandomizer = new PseudoRandomizers().GetNumberRandomizer(); + + [Benchmark] + public byte NextByte() => _intRandomizer.NextByte(); + + [Benchmark] + public byte NextByteInRange() => _intRandomizer.NextByte(byte.MinValue, byte.MaxValue); +} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/ByteArray.RandomizerExtensionsBenchmarks.cs b/Random.Benchmarks/Extensions/ByteArray.RandomizerExtensionsBenchmarks.cs new file mode 100644 index 0000000..3f9cb19 --- /dev/null +++ b/Random.Benchmarks/Extensions/ByteArray.RandomizerExtensionsBenchmarks.cs @@ -0,0 +1,23 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Attributes; +using Depra.Random.Application.System.Collections; +using Depra.Random.Domain.Extensions; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Benchmarks.Extensions; + +[MemoryDiagnoser] +public class ByteArrayRandomizerExtensionsBenchmarks +{ + private const int BYTE_ARRAY_LENGTH = 8; + + private IArrayRandomizer _bytesRandomizer; + + [GlobalSetup] + public void Setup() => _bytesRandomizer = new PseudoRandomizers().GetArrayRandomizer(); + + [Benchmark] + public byte[] NextByteArray() => _bytesRandomizer.NextBytes(BYTE_ARRAY_LENGTH); +} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/CharArray.RandomizerExtensionsBenchmarks.cs b/Random.Benchmarks/Extensions/CharArray.RandomizerExtensionsBenchmarks.cs new file mode 100644 index 0000000..6f18a6e --- /dev/null +++ b/Random.Benchmarks/Extensions/CharArray.RandomizerExtensionsBenchmarks.cs @@ -0,0 +1,22 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Attributes; +using Depra.Random.Application.System.Collections; +using Depra.Random.Domain.Extensions; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Benchmarks.Extensions; + +public class CharArrayRandomizerExtensionsBenchmarks +{ + private const int CHAR_ARRAY_LENGTH = 8; + + private INumberRandomizer _intRandomizer; + + [GlobalSetup] + public void Setup() => _intRandomizer = new PseudoRandomizers().GetNumberRandomizer(); + + [Benchmark] + public void NextChars() => _intRandomizer.NextChars(CHAR_ARRAY_LENGTH, true); +} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/Decimal.RandomizerExtensionsBenchmarks.cs b/Random.Benchmarks/Extensions/Decimal.RandomizerExtensionsBenchmarks.cs new file mode 100644 index 0000000..1b61978 --- /dev/null +++ b/Random.Benchmarks/Extensions/Decimal.RandomizerExtensionsBenchmarks.cs @@ -0,0 +1,23 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Attributes; +using Depra.Random.Application.System.Collections; +using Depra.Random.Domain.Extensions; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Benchmarks.Extensions; + +public class DecimalRandomizerExtensionsBenchmarks +{ + private INumberRandomizer _intRandomizer; + + [GlobalSetup] + public void Setup() => _intRandomizer = new PseudoRandomizers().GetNumberRandomizer(); + + [Benchmark] + public decimal NextDecimal() => _intRandomizer.NextDecimal(); + + [Benchmark] + public decimal NextDecimalInRange() => _intRandomizer.NextDecimal(decimal.MinValue, decimal.MaxValue); +} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/Double.RandomizerExtensionsBenchmarks.cs b/Random.Benchmarks/Extensions/Double.RandomizerExtensionsBenchmarks.cs new file mode 100644 index 0000000..d189400 --- /dev/null +++ b/Random.Benchmarks/Extensions/Double.RandomizerExtensionsBenchmarks.cs @@ -0,0 +1,20 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Attributes; +using Depra.Random.Application.System.Collections; +using Depra.Random.Domain.Extensions; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Benchmarks.Extensions; + +public class DoubleRandomizerExtensionsBenchmarks +{ + private ITypedRandomizer _doubleRandomizer; + + [GlobalSetup] + public void Setup() => _doubleRandomizer = new PseudoRandomizers().GetTypedRandomizer(); + + [Benchmark] + public double NextDoubleInRange() => _doubleRandomizer.NextDouble(double.MinValue, double.MaxValue); +} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/Int16.RandomizerExtensionsBenchmarks.cs b/Random.Benchmarks/Extensions/Int16.RandomizerExtensionsBenchmarks.cs new file mode 100644 index 0000000..43dd132 --- /dev/null +++ b/Random.Benchmarks/Extensions/Int16.RandomizerExtensionsBenchmarks.cs @@ -0,0 +1,23 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Attributes; +using Depra.Random.Application.System.Collections; +using Depra.Random.Domain.Extensions; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Benchmarks.Extensions; + +public class Int16RandomizerExtensionsBenchmarks +{ + private INumberRandomizer _intRandomizer; + + [GlobalSetup] + public void Setup() => _intRandomizer = new PseudoRandomizers().GetNumberRandomizer(); + + [Benchmark] + public short NextShort() => _intRandomizer.NextShort(); + + [Benchmark] + public short NextShortInRange() => _intRandomizer.NextShort(short.MinValue, short.MaxValue); +} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/Int64.RandomizerExtensionsBenchmarks.cs b/Random.Benchmarks/Extensions/Int64.RandomizerExtensionsBenchmarks.cs new file mode 100644 index 0000000..01d3bab --- /dev/null +++ b/Random.Benchmarks/Extensions/Int64.RandomizerExtensionsBenchmarks.cs @@ -0,0 +1,23 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Attributes; +using Depra.Random.Application.System.Collections; +using Depra.Random.Domain.Extensions; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Benchmarks.Extensions; + +public class Int64RandomizerExtensionsBenchmarks +{ + private IArrayRandomizer _byteArrayRandomizer; + + [GlobalSetup] + public void Setup() => _byteArrayRandomizer = new PseudoRandomizers().GetArrayRandomizer(); + + [Benchmark] + public long NextLong() => _byteArrayRandomizer.NextLong(); + + [Benchmark] + public long NextLongInRange() => _byteArrayRandomizer.NextLong(long.MinValue, long.MaxValue); +} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Boolean.cs b/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Boolean.cs deleted file mode 100644 index bb8c76f..0000000 --- a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Boolean.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright © 2022 Nikolay Melnikov. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -using BenchmarkDotNet.Attributes; -using Depra.Random.Domain.Extensions; - -namespace Depra.Random.Benchmarks.Extensions; - -public partial class RandomizerExtensionsBenchmarks -{ - [Benchmark] - public bool NextBool() => _random.NextBoolean(); -} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Byte.cs b/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Byte.cs deleted file mode 100644 index 31f7763..0000000 --- a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Byte.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright © 2022 Nikolay Melnikov. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -using BenchmarkDotNet.Attributes; -using Depra.Random.Domain.Extensions; - -namespace Depra.Random.Benchmarks.Extensions; - -public partial class RandomizerExtensionsBenchmarks -{ - private const int BYTE_ARRAY_LENGTH = 8; - - [Benchmark] - public byte NextByte() => _random.NextByte(); - - [Benchmark] - public byte NextByteInRange() => _random.NextByte(byte.MinValue, byte.MaxValue); - - [Benchmark] - public byte[] NextByteArray() => _random.NextBytes(BYTE_ARRAY_LENGTH); -} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Chars.cs b/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Chars.cs deleted file mode 100644 index 2459a53..0000000 --- a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Chars.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright © 2022 Nikolay Melnikov. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -using BenchmarkDotNet.Attributes; -using Depra.Random.Domain.Extensions; -using Depra.Random.Extensions; - -namespace Depra.Random.Benchmarks.Extensions; - -public partial class RandomizerExtensionsBenchmarks -{ - private const int CHAR_ARRAY_LENGTH = 8; - - [Benchmark] - public void NextChars() => _random.NextChars(CHAR_ARRAY_LENGTH, true); -} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Decimal.cs b/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Decimal.cs deleted file mode 100644 index dd3bfa3..0000000 --- a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Decimal.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright © 2022 Nikolay Melnikov. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -using BenchmarkDotNet.Attributes; -using Depra.Random.Domain.Extensions; - -namespace Depra.Random.Benchmarks.Extensions; - -public partial class RandomizerExtensionsBenchmarks -{ - [Benchmark] - public decimal NextDecimal() => _random.NextDecimal(); - - [Benchmark] - public decimal NextDecimalInRange() => _random.NextDecimal(decimal.MinValue, decimal.MaxValue); -} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Float.cs b/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Float.cs deleted file mode 100644 index ead448c..0000000 --- a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Float.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright © 2022 Nikolay Melnikov. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -using BenchmarkDotNet.Attributes; -using Depra.Random.Domain.Extensions; - -namespace Depra.Random.Benchmarks.Extensions; - -public partial class RandomizerExtensionsBenchmarks -{ - [Benchmark] - public float NextFloat() => _random.NextFloat(); - - [Benchmark] - public float NextFloatInRange() => _random.NextFloat(float.MinValue, float.MaxValue); -} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Int16.cs b/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Int16.cs deleted file mode 100644 index a3b5f24..0000000 --- a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Int16.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright © 2022 Nikolay Melnikov. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -using BenchmarkDotNet.Attributes; -using Depra.Random.Domain.Extensions; - -namespace Depra.Random.Benchmarks.Extensions; - -public partial class RandomizerExtensionsBenchmarks -{ - [Benchmark] - public short NextShort() => _random.NextShort(); - - [Benchmark] - public short NextShortInRange() => _random.NextShort(short.MinValue, short.MaxValue); -} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Int64.cs b/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Int64.cs deleted file mode 100644 index d792e5a..0000000 --- a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.Int64.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright © 2022 Nikolay Melnikov. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -using BenchmarkDotNet.Attributes; -using Depra.Random.Domain.Extensions; -using Depra.Random.Extensions; - -namespace Depra.Random.Benchmarks.Extensions; - -public partial class RandomizerExtensionsBenchmarks -{ - [Benchmark] - public long NextLong() => _random.NextLong(); - - [Benchmark] - public long NextLongInRange() => _random.NextLong(long.MinValue, long.MaxValue); -} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.SByte.cs b/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.SByte.cs deleted file mode 100644 index fadc137..0000000 --- a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.SByte.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright © 2022 Nikolay Melnikov. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -using BenchmarkDotNet.Attributes; -using Depra.Random.Domain.Extensions; - -namespace Depra.Random.Benchmarks.Extensions; - -public partial class RandomizerExtensionsBenchmarks -{ - [Benchmark] - public sbyte NextSByte() => _random.NextSByte(); - - [Benchmark] - public sbyte NextSByteInRange() => _random.NextSByte(sbyte.MinValue, sbyte.MaxValue); -} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.String.cs b/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.String.cs deleted file mode 100644 index f38c9de..0000000 --- a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.String.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright © 2022 Nikolay Melnikov. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -using BenchmarkDotNet.Attributes; -using Depra.Random.Domain.Extensions; - -namespace Depra.Random.Benchmarks.Extensions; - -public partial class RandomizerExtensionsBenchmarks -{ - private const int STRING_LENGTH = 8; - - [Benchmark] - public string NextString() => _random.NextString(STRING_LENGTH, true); -} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.UInt16.cs b/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.UInt16.cs deleted file mode 100644 index 807f0fb..0000000 --- a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.UInt16.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright © 2022 Nikolay Melnikov. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -using BenchmarkDotNet.Attributes; -using Depra.Random.Domain.Extensions; - -namespace Depra.Random.Benchmarks.Extensions; - -public partial class RandomizerExtensionsBenchmarks -{ - [Benchmark] - public ushort NextUShort() => _random.NextUShort(); - - [Benchmark] - public ushort NextUShortInRange() => _random.NextUShort(ushort.MinValue, ushort.MaxValue); -} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.UInt32.cs b/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.UInt32.cs deleted file mode 100644 index 4870f84..0000000 --- a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.UInt32.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright © 2022 Nikolay Melnikov. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -using BenchmarkDotNet.Attributes; -using Depra.Random.Domain.Extensions; - -namespace Depra.Random.Benchmarks.Extensions; - -public partial class RandomizerExtensionsBenchmarks -{ - [Benchmark] - public uint NextUInt() => _random.NextUInt(); - - [Benchmark] - public uint NextUIntInRange() => _random.NextUInt(uint.MinValue, uint.MaxValue); -} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.UInt64.cs b/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.UInt64.cs deleted file mode 100644 index 0655eb1..0000000 --- a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.UInt64.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright © 2022 Nikolay Melnikov. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -using BenchmarkDotNet.Attributes; -using Depra.Random.Domain.Extensions; - -namespace Depra.Random.Benchmarks.Extensions; - -public partial class RandomizerExtensionsBenchmarks -{ - [Benchmark] - public ulong NextULong() => _random.NextULong(); - - [Benchmark] - public ulong NextULongInRange() => _random.NextULong(ulong.MinValue, ulong.MaxValue); -} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.cs b/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.cs deleted file mode 100644 index 5bb094e..0000000 --- a/Random.Benchmarks/Extensions/RandomizerExtensionsBenchmarks.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright © 2022 Nikolay Melnikov. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -using BenchmarkDotNet.Attributes; -using Depra.Random.Application.System; -using Depra.Random.Domain.Extensions; - -namespace Depra.Random.Benchmarks.Extensions; - -[MemoryDiagnoser] -public partial class RandomizerExtensionsBenchmarks -{ - private PseudoRandom _random; - - [GlobalSetup] - public void Setup() => _random = new PseudoRandom(); - - [Benchmark] - public double NextDoubleInRange() => _random.NextDouble(double.MinValue, double.MaxValue); -} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/SByte.RandomizerExtensionsBenchmarks.cs b/Random.Benchmarks/Extensions/SByte.RandomizerExtensionsBenchmarks.cs new file mode 100644 index 0000000..0018d43 --- /dev/null +++ b/Random.Benchmarks/Extensions/SByte.RandomizerExtensionsBenchmarks.cs @@ -0,0 +1,23 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Attributes; +using Depra.Random.Application.System.Collections; +using Depra.Random.Domain.Extensions; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Benchmarks.Extensions; + +public class SByteRandomizerExtensionsBenchmarks +{ + private INumberRandomizer _intRandomizer; + + [GlobalSetup] + public void Setup() => _intRandomizer = new PseudoRandomizers().GetNumberRandomizer(); + + [Benchmark] + public sbyte NextSByte() => _intRandomizer.NextSByte(); + + [Benchmark] + public sbyte NextSByteInRange() => _intRandomizer.NextSByte(sbyte.MinValue, sbyte.MaxValue); +} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/Single.RandomizerExtensionsBenchmarks.cs b/Random.Benchmarks/Extensions/Single.RandomizerExtensionsBenchmarks.cs new file mode 100644 index 0000000..3da18a1 --- /dev/null +++ b/Random.Benchmarks/Extensions/Single.RandomizerExtensionsBenchmarks.cs @@ -0,0 +1,23 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Attributes; +using Depra.Random.Application.System.Collections; +using Depra.Random.Domain.Extensions; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Benchmarks.Extensions; + +public class SingleRandomizerExtensionsBenchmarks +{ + private ITypedRandomizer _doubleRandomizer; + + [GlobalSetup] + public void Setup() => _doubleRandomizer = new PseudoRandomizers().GetTypedRandomizer(); + + [Benchmark] + public float NextFloat() => _doubleRandomizer.NextFloat(); + + [Benchmark] + public float NextFloatInRange() => _doubleRandomizer.NextFloat(float.MinValue, float.MaxValue); +} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/String.RandomizerExtensionsBenchmarks.cs b/Random.Benchmarks/Extensions/String.RandomizerExtensionsBenchmarks.cs new file mode 100644 index 0000000..7318910 --- /dev/null +++ b/Random.Benchmarks/Extensions/String.RandomizerExtensionsBenchmarks.cs @@ -0,0 +1,23 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Attributes; +using Depra.Random.Application.System.Collections; +using Depra.Random.Domain.Extensions; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Benchmarks.Extensions; + +public class StringRandomizerExtensionsBenchmarks +{ + private INumberRandomizer _intRandomizer; + + [Params(10, 100)] + public int StringLength { get; set; } + + [GlobalSetup] + public void Setup() => _intRandomizer = new PseudoRandomizers().GetNumberRandomizer(); + + [Benchmark] + public string NextString() => _intRandomizer.NextString(StringLength, true); +} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/UInt16.RandomizerExtensionsBenchmarks.cs b/Random.Benchmarks/Extensions/UInt16.RandomizerExtensionsBenchmarks.cs new file mode 100644 index 0000000..fc36158 --- /dev/null +++ b/Random.Benchmarks/Extensions/UInt16.RandomizerExtensionsBenchmarks.cs @@ -0,0 +1,23 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Attributes; +using Depra.Random.Application.System.Collections; +using Depra.Random.Domain.Extensions; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Benchmarks.Extensions; + +public class UInt16RandomizerExtensionsBenchmarks +{ + private INumberRandomizer _intRandomizer; + + [GlobalSetup] + public void Setup() => _intRandomizer = new PseudoRandomizers().GetNumberRandomizer(); + + [Benchmark] + public ushort NextUShort() => _intRandomizer.NextUShort(); + + [Benchmark] + public ushort NextUShortInRange() => _intRandomizer.NextUShort(ushort.MinValue, ushort.MaxValue); +} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/UInt32.RandomizerExtensionsBenchmarks.cs b/Random.Benchmarks/Extensions/UInt32.RandomizerExtensionsBenchmarks.cs new file mode 100644 index 0000000..6d1a188 --- /dev/null +++ b/Random.Benchmarks/Extensions/UInt32.RandomizerExtensionsBenchmarks.cs @@ -0,0 +1,23 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Attributes; +using Depra.Random.Application.System.Collections; +using Depra.Random.Domain.Extensions; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Benchmarks.Extensions; + +public class UInt32RandomizerExtensionsBenchmarks +{ + private INumberRandomizer _intRandomizer; + + [GlobalSetup] + public void Setup() => _intRandomizer = new PseudoRandomizers().GetNumberRandomizer(); + + [Benchmark] + public uint NextUInt() => _intRandomizer.NextUInt(); + + [Benchmark] + public uint NextUIntInRange() => _intRandomizer.NextUInt(uint.MinValue, uint.MaxValue); +} \ No newline at end of file diff --git a/Random.Benchmarks/Extensions/UInt64.RandomizerExtensionsBenchmarks.cs b/Random.Benchmarks/Extensions/UInt64.RandomizerExtensionsBenchmarks.cs new file mode 100644 index 0000000..1bd5312 --- /dev/null +++ b/Random.Benchmarks/Extensions/UInt64.RandomizerExtensionsBenchmarks.cs @@ -0,0 +1,23 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Attributes; +using Depra.Random.Application.System.Collections; +using Depra.Random.Domain.Extensions; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Benchmarks.Extensions; + +public class UInt64RandomizerExtensionsBenchmarks +{ + private IArrayRandomizer _byteArrayRandomizer; + + [GlobalSetup] + public void Setup() => _byteArrayRandomizer = new PseudoRandomizers().GetArrayRandomizer(); + + [Benchmark] + public ulong NextULong() => _byteArrayRandomizer.NextULong(); + + [Benchmark] + public ulong NextULongInRange() => _byteArrayRandomizer.NextULong(ulong.MinValue, ulong.MaxValue); +} \ No newline at end of file diff --git a/Random.Benchmarks/Program.cs b/Random.Benchmarks/Program.cs index e674144..bfd3376 100644 --- a/Random.Benchmarks/Program.cs +++ b/Random.Benchmarks/Program.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Diagnosers; using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Order; using BenchmarkDotNet.Running; @@ -18,7 +19,8 @@ private static void Main() BenchmarkRunner.Run(DefaultConfig.Instance .AddValidator(JitOptimizationsValidator.FailOnError) .AddJob(Job.Default.WithToolchain(InProcessEmitToolchain.Instance)) - .WithOrderer(new DefaultOrderer(SummaryOrderPolicy.FastestToSlowest))); + .WithOrderer(new DefaultOrderer(SummaryOrderPolicy.FastestToSlowest)) + .AddDiagnoser(MemoryDiagnoser.Default)); // BenchmarkRunner.Run(typeof(Program).Assembly, DefaultConfig.Instance // .AddValidator(JitOptimizationsValidator.FailOnError) diff --git a/Random.Benchmarks/Randomizers/ConcurrentRandomBenchmarks.cs b/Random.Benchmarks/Randomizers/ConcurrentRandomBenchmarks.cs index 48e1c99..409feab 100644 --- a/Random.Benchmarks/Randomizers/ConcurrentRandomBenchmarks.cs +++ b/Random.Benchmarks/Randomizers/ConcurrentRandomBenchmarks.cs @@ -2,45 +2,43 @@ // SPDX-License-Identifier: Apache-2.0 using BenchmarkDotNet.Attributes; -using Depra.Random.Application.System; -using Depra.Random.Domain.Extensions; +using Depra.Random.Application.System.Randoms; namespace Depra.Random.Benchmarks.Randomizers; -[MemoryDiagnoser] public class ConcurrentRandomBenchmarks { private System.Random _random; - private ConcurrentPseudoRandom _concurrentRandom; + private ConcurrentPseudoRandom _concurrentPseudoRandom; [GlobalSetup] public void Setup() { _random = new System.Random(); - _concurrentRandom = new ConcurrentPseudoRandom(); + _concurrentPseudoRandom = new ConcurrentPseudoRandom(); } [Benchmark(Baseline = true)] - public int NextInt32_Pseudo() => _random.Next(); + public int NextInt32_Manual() => _random.Next(); [Benchmark] - public int NextInt32_Concurrent() => _concurrentRandom.Next(); + public int NextInt32_Concurrent() => _concurrentPseudoRandom.Next(); [Benchmark] - public int NextInt32_Pseudo_InRange() => _random.Next(int.MinValue, int.MaxValue); + public int NextInt32_Manual_InRange() => _random.Next(int.MinValue, int.MaxValue); [Benchmark] - public int NextInt32_Concurrent_InRange() => _concurrentRandom.Next(int.MinValue, int.MaxValue); + public int NextInt32_Concurrent_InRange() => _concurrentPseudoRandom.Next(int.MinValue, int.MaxValue); [Benchmark] - public double NextDouble_Pseudo() => _random.NextDouble(); + public double NextDouble_Manual() => _random.NextDouble(); [Benchmark] - public double NextDouble_Concurrent() => _concurrentRandom.NextDouble(); + public double NextDouble_Concurrent() => _concurrentPseudoRandom.NextDouble(); [Benchmark] - public void NextBytes_Pseudo() => _random.NextBytes(new byte[64]); + public void NextBytes_Manual() => _random.NextBytes(new byte[64]); [Benchmark] - public void NextBytes_Concurrent() => _concurrentRandom.NextBytes(64); + public void NextBytes_Concurrent() => _concurrentPseudoRandom.NextBytes(new byte[64]); } \ No newline at end of file diff --git a/Random.Benchmarks/Randomizers/CryptoRandomBenchmarks.cs b/Random.Benchmarks/Randomizers/CryptoRandomBenchmarks.cs index 063e17f..86d2b7c 100644 --- a/Random.Benchmarks/Randomizers/CryptoRandomBenchmarks.cs +++ b/Random.Benchmarks/Randomizers/CryptoRandomBenchmarks.cs @@ -2,48 +2,46 @@ // SPDX-License-Identifier: Apache-2.0 using BenchmarkDotNet.Attributes; -using Depra.Random.Application.System; -using Depra.Random.Domain.Randomizers; +using Depra.Random.Application.System.Randoms; namespace Depra.Random.Benchmarks.Randomizers; -[MemoryDiagnoser] public class CryptoRandomBenchmarks { - private CryptoRandomizer _cryptoRandomizer; private System.Random _random; + private CryptoRandom _cryptoRandom; [GlobalSetup] public void SetUp() { - _cryptoRandomizer = new CryptoRandomizer(); + _cryptoRandom = new CryptoRandom(); _random = new System.Random(); } [GlobalCleanup] - public void TearDown() => _cryptoRandomizer.Dispose(); + public void TearDown() => _cryptoRandom.Dispose(); [Benchmark(Baseline = true)] - public int NextInt32_Pseudo() => _random.Next(); + public int NextInt32_Manual() => _random.Next(); [Benchmark] - public int NextInt32_Crypto() => _cryptoRandomizer.Next(); + public int NextInt32_Crypto() => _cryptoRandom.Next(); [Benchmark] - public int NextInt32_Pseudo_InRange() => _random.Next(int.MinValue, int.MaxValue); + public int NextInt32_Manual_InRange() => _random.Next(int.MinValue, int.MaxValue); [Benchmark] - public int NextInt32_Crypto_InRange() => _cryptoRandomizer.Next(int.MinValue, int.MaxValue); + public int NextInt32_Crypto_InRange() => _cryptoRandom.Next(int.MinValue, int.MaxValue); [Benchmark] - public double NextDouble_Pseudo() => _random.NextDouble(); + public double NextDouble_Manual() => _random.NextDouble(); [Benchmark] - public double NextDouble_Crypto() => ((ITypedRandomizer)_cryptoRandomizer).Next(); + public double NextDouble_Crypto() => _cryptoRandom.NextDouble(); [Benchmark] - public void NextBytes_Pseudo() => _random.NextBytes(new byte[64]); + public void NextBytes_Manual() => _random.NextBytes(new byte[64]); [Benchmark] - public void NextBytes_Crypto() => ((IArrayRandomizer)_cryptoRandomizer).Next(new byte[64]); + public void NextBytes_Crypto() => _cryptoRandom.NextBytes(new byte[64]); } \ No newline at end of file diff --git a/Random.Benchmarks/Service/RandomServiceBenchmarks.cs b/Random.Benchmarks/Service/RandomServiceBenchmarks.cs index 3b51937..f8b87c3 100644 --- a/Random.Benchmarks/Service/RandomServiceBenchmarks.cs +++ b/Random.Benchmarks/Service/RandomServiceBenchmarks.cs @@ -4,36 +4,34 @@ using BenchmarkDotNet.Attributes; using Depra.Random.Application.ServiceBuilder; using Depra.Random.Application.Services; -using Depra.Random.Application.System; +using Depra.Random.Application.System.Collections; using Depra.Random.Domain.Randomizers; namespace Depra.Random.Benchmarks.Service; -[MemoryDiagnoser] public class RandomServiceBenchmarks { - private const int BYTE_BUFFER_SIZE = 32; - - private global::System.Random _random; + private System.Random _random; private IRandomService _randomService; private ITypedRandomizer _intRandomizer; private ITypedRandomizer _doubleRandomizer; private IArrayRandomizer _bytesRandomizer; + [Params(8)] + public int BufferSize { get; set; } + [GlobalSetup] public void Setup() { - _random = new global::System.Random(); + _random = new System.Random(); - var randomizer = new PseudoRandom(); - _intRandomizer = randomizer; - _doubleRandomizer = randomizer; - _bytesRandomizer = randomizer; + var pseudoRandomizers = new PseudoRandomizers(); + _intRandomizer = (ITypedRandomizer) pseudoRandomizers.GetRandomizer(typeof(int)); + _doubleRandomizer = (ITypedRandomizer) pseudoRandomizers.GetRandomizer(typeof(double)); + _bytesRandomizer = (IArrayRandomizer) pseudoRandomizers.GetRandomizer(typeof(byte[])); _randomService = new RandomServiceBuilder() - .With(_intRandomizer) - .With(_doubleRandomizer) - .With(_bytesRandomizer) + .With(pseudoRandomizers) .Build(); } @@ -56,11 +54,12 @@ public void Setup() public double NextDouble_Depra_WithCache() => _doubleRandomizer.Next(); [Benchmark] - public void NextBytes_Manual() => _random.NextBytes(new byte[BYTE_BUFFER_SIZE]); + public void NextBytes_Manual() => _random.NextBytes(new byte[BufferSize]); [Benchmark] - public void NextBytes_Depra() => _randomService.GetArrayRandomizer().Next(new byte[BYTE_BUFFER_SIZE]); + public void NextBytes_Depra() => + _randomService.GetArrayRandomizer().Next(new byte[BufferSize]); [Benchmark] - public void NextBytes_Depra_WithCache() => _bytesRandomizer.Next(new byte[BYTE_BUFFER_SIZE]); + public void NextBytes_Depra_WithCache() => _bytesRandomizer.Next(new byte[BufferSize]); } \ No newline at end of file diff --git a/Random/Application/Extensions/ArrayExtensions.cs b/Random/Application/Extensions/ArrayExtensions.cs index 644ef69..27aa70f 100644 --- a/Random/Application/Extensions/ArrayExtensions.cs +++ b/Random/Application/Extensions/ArrayExtensions.cs @@ -4,7 +4,7 @@ using System; using Depra.Random.Domain.Randomizers; -namespace Depra.Random.Extensions +namespace Depra.Random.Application.Extensions { /// /// extensions. diff --git a/Random/Application/Extensions/EnumerableExtensions.cs b/Random/Application/Extensions/EnumerableExtensions.cs index 26b5234..8dd659c 100644 --- a/Random/Application/Extensions/EnumerableExtensions.cs +++ b/Random/Application/Extensions/EnumerableExtensions.cs @@ -7,7 +7,7 @@ using Depra.Random.Domain.Extensions; using Depra.Random.Domain.Randomizers; -namespace Depra.Random.Extensions +namespace Depra.Random.Application.Extensions { public static class EnumerableExtensions { diff --git a/Random/Application/Extensions/ListExtensions.cs b/Random/Application/Extensions/ListExtensions.cs index 094b966..8ba4f12 100644 --- a/Random/Application/Extensions/ListExtensions.cs +++ b/Random/Application/Extensions/ListExtensions.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using Depra.Random.Domain.Randomizers; -namespace Depra.Random.Extensions +namespace Depra.Random.Application.Extensions { public static class ListExtensions { diff --git a/Random/Application/Extensions/RandomizerCollectionExtensions.cs b/Random/Application/Extensions/RandomizerCollectionExtensions.cs new file mode 100644 index 0000000..a1d6c49 --- /dev/null +++ b/Random/Application/Extensions/RandomizerCollectionExtensions.cs @@ -0,0 +1,19 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Application.Extensions +{ + internal static class RandomizerCollectionExtensions + { + public static ITypedRandomizer GetTypedRandomizer(this IRandomizerCollection randomizerCollection) => + (ITypedRandomizer) randomizerCollection.GetRandomizer(typeof(T)); + + public static INumberRandomizer GetNumberRandomizer(this IRandomizerCollection randomizerCollection) => + (INumberRandomizer) randomizerCollection.GetRandomizer(typeof(T)); + + public static IArrayRandomizer GetArrayRandomizer(this IRandomizerCollection randomizerCollection) => + (IArrayRandomizer) randomizerCollection.GetRandomizer(typeof(T)); + } +} \ No newline at end of file diff --git a/Random/Application/ServiceBuilder/IRandomServiceBuilder.cs b/Random/Application/ServiceBuilder/IRandomServiceBuilder.cs index b14ba94..d99fbce 100644 --- a/Random/Application/ServiceBuilder/IRandomServiceBuilder.cs +++ b/Random/Application/ServiceBuilder/IRandomServiceBuilder.cs @@ -1,3 +1,6 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + using System; using Depra.Random.Application.Services; using Depra.Random.Domain.Randomizers; diff --git a/Random/Application/ServiceBuilder/RandomServiceBuilder.cs b/Random/Application/ServiceBuilder/RandomServiceBuilder.cs index 1b07808..9e7ed2d 100644 --- a/Random/Application/ServiceBuilder/RandomServiceBuilder.cs +++ b/Random/Application/ServiceBuilder/RandomServiceBuilder.cs @@ -1,3 +1,6 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + using System; using System.Collections.Generic; using Depra.Random.Application.Services; @@ -19,7 +22,6 @@ public IRandomServiceBuilder With(Type valueType, IRandomizer randomizer) Throw.RandomizerForTypeAlreadyRegistered(valueType); } - Console.WriteLine(valueType.Name); _randomizers.Add(valueType, randomizer); return this; diff --git a/Random/Application/ServiceBuilder/RandomServiceBuilderExtensions.cs b/Random/Application/ServiceBuilder/RandomServiceBuilderExtensions.cs index 2eea8ce..b0912f8 100644 --- a/Random/Application/ServiceBuilder/RandomServiceBuilderExtensions.cs +++ b/Random/Application/ServiceBuilder/RandomServiceBuilderExtensions.cs @@ -1,3 +1,6 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + using System; using Depra.Random.Domain.Randomizers; @@ -5,11 +8,11 @@ namespace Depra.Random.Application.ServiceBuilder { public static class RandomServiceBuilderExtensions { - public static IRandomServiceBuilder With(this IRandomServiceBuilder builder, ITypedRandomizer randomizer) => - builder.With(typeof(T), randomizer); + public static IRandomServiceBuilder With(this IRandomServiceBuilder builder, + ITypedRandomizer randomizer) => builder.With(typeof(T), randomizer); - public static IRandomServiceBuilder With(this IRandomServiceBuilder builder, IArrayRandomizer randomizer) => - builder.With(typeof(T), randomizer); + public static IRandomServiceBuilder With(this IRandomServiceBuilder builder, + IArrayRandomizer randomizer) => builder.With(typeof(T), randomizer); public static IRandomServiceBuilder With(this IRandomServiceBuilder builder, IRandomizerCollection fromCollection) @@ -17,10 +20,8 @@ public static IRandomServiceBuilder With(this IRandomServiceBuilder builder, var randomizers = fromCollection.GetAllRandomizers(); foreach (var randomizer in randomizers) { - foreach (var valueType in randomizer.ValueTypes) - { - builder.With(valueType, randomizer); - } + Console.WriteLine(randomizer.ValueType); + builder.With(randomizer.ValueType, randomizer); } return builder; diff --git a/Random/Application/Services/RandomServiceExtensions.cs b/Random/Application/Services/RandomServiceExtensions.cs index 5197196..844a0da 100644 --- a/Random/Application/Services/RandomServiceExtensions.cs +++ b/Random/Application/Services/RandomServiceExtensions.cs @@ -1,3 +1,6 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + using Depra.Random.Domain.Randomizers; namespace Depra.Random.Application.Services diff --git a/Random/Application/System/Collections/ConcurrentPseudoRandomizers.cs b/Random/Application/System/Collections/ConcurrentPseudoRandomizers.cs new file mode 100644 index 0000000..d301454 --- /dev/null +++ b/Random/Application/System/Collections/ConcurrentPseudoRandomizers.cs @@ -0,0 +1,36 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Collections.Generic; +using Depra.Random.Application.System.Mapping; +using Depra.Random.Application.System.Proxy; +using Depra.Random.Application.System.Randoms; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Application.System.Collections +{ + public sealed class ConcurrentPseudoRandomizers : IRandomizerCollection + { + private static readonly SystemRandomizersMapper RANDOMIZERS_MAPPER; + + static ConcurrentPseudoRandomizers() + { + var randomImpl = +#if NET6_0_OR_GREATER + new global::System.Random(); +#else + new ConcurrentPseudoRandom(); +#endif + + RANDOMIZERS_MAPPER = new SystemRandomizersMapper( + new IntRandomProxy(randomImpl), + new DoubleRandomProxy(randomImpl), + new ByteArrayRandomProxy(randomImpl)); + } + + public IRandomizer GetRandomizer(Type valueType) => RANDOMIZERS_MAPPER.GetRandomizer(valueType); + + public IEnumerable GetAllRandomizers() => RANDOMIZERS_MAPPER.GetAllRandomizers(); + } +} \ No newline at end of file diff --git a/Random/Application/System/Collections/CryptoRandomizers.cs b/Random/Application/System/Collections/CryptoRandomizers.cs new file mode 100644 index 0000000..59e3d4d --- /dev/null +++ b/Random/Application/System/Collections/CryptoRandomizers.cs @@ -0,0 +1,30 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Collections.Generic; +using Depra.Random.Application.System.Mapping; +using Depra.Random.Application.System.Proxy; +using Depra.Random.Application.System.Randoms; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Application.System.Collections +{ + public sealed class CryptoRandomizers : IRandomizerCollection + { + private readonly SystemRandomizersMapper _randomizersMapper; + + public CryptoRandomizers() + { + var random = new CryptoRandom(); + _randomizersMapper = new SystemRandomizersMapper( + new IntRandomProxy(random), + new DoubleRandomProxy(random), + new ByteArrayRandomProxy(random)); + } + + public IRandomizer GetRandomizer(Type valueType) => _randomizersMapper.GetRandomizer(valueType); + + public IEnumerable GetAllRandomizers() => _randomizersMapper.GetAllRandomizers(); + } +} \ No newline at end of file diff --git a/Random/Application/System/Collections/PseudoRandomizers.cs b/Random/Application/System/Collections/PseudoRandomizers.cs new file mode 100644 index 0000000..60e21c7 --- /dev/null +++ b/Random/Application/System/Collections/PseudoRandomizers.cs @@ -0,0 +1,32 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Collections.Generic; +using Depra.Random.Application.System.Mapping; +using Depra.Random.Application.System.Proxy; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Application.System.Collections +{ + /// + /// Decorator for , to support the contract. + /// + public sealed class PseudoRandomizers : IRandomizerCollection + { + private readonly SystemRandomizersMapper _randomizersMapper; + + public PseudoRandomizers() + { + var random = new global::System.Random(); + _randomizersMapper = new SystemRandomizersMapper( + new IntRandomProxy(random), + new DoubleRandomProxy(random), + new ByteArrayRandomProxy(random)); + } + + public IRandomizer GetRandomizer(Type valueType) => _randomizersMapper.GetRandomizer(valueType); + + public IEnumerable GetAllRandomizers() => _randomizersMapper.GetAllRandomizers(); + } +} \ No newline at end of file diff --git a/Random/Application/System/ConcurrentPseudoRandom.cs b/Random/Application/System/ConcurrentPseudoRandom.cs deleted file mode 100644 index 5002cb5..0000000 --- a/Random/Application/System/ConcurrentPseudoRandom.cs +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright © 2022 Nikolay Melnikov. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -using System; -using System.Collections.Generic; -using Depra.Random.Domain.Randomizers; - -namespace Depra.Random.Application.System -{ - /// - /// A random number generator guaranteeing thread safety. - /// - public sealed class ConcurrentPseudoRandom : ITypedRandomizer, ITypedRandomizer, - IArrayRandomizer - { - private static readonly global::System.Random IMPL; - private static readonly Type[] VALUE_TYPES = {typeof(int), typeof(double), typeof(byte[])}; - - public IEnumerable ValueTypes => VALUE_TYPES; - - public int Next() => IMPL.Next(1, int.MaxValue); - - public int Next(int maxExclusive) => IMPL.Next(maxExclusive); - - public int Next(int minInclusive, int maxExclusive) => IMPL.Next(minInclusive, maxExclusive); - - double ITypedRandomizer.Next() => IMPL.NextDouble(); - - void IArrayRandomizer.Next(byte[] buffer) => IMPL.NextBytes(buffer); - - static ConcurrentPseudoRandom() - { - IMPL = -#if NET6_0_OR_GREATER - new global::System.Random(); -#else - new ConcurrentRandomImpl(); -#endif - } - - private class ConcurrentRandomImpl : global::System.Random - { - private static readonly global::System.Random GLOBAL = new global::System.Random(); - - [ThreadStatic] private static global::System.Random _local; - - public override int Next() => Next(1, int.MaxValue); - - public override int Next(int maxExclusive) => Next(1, maxExclusive); - - public override int Next(int minInclusive, int maxExclusive) - { - var inst = _local; - if (inst != null) - { - return inst.Next(minInclusive, maxExclusive); - } - - _local = inst = CreateRandom(); - return inst.Next(minInclusive, maxExclusive); - } - - public override double NextDouble() - { - var inst = _local; - if (inst != null) - { - return inst.NextDouble(); - } - - _local = inst = CreateRandom(); - return inst.NextDouble(); - } - - public override void NextBytes(byte[] buffer) - { - var inst = _local; - if (inst != null) - { - inst.NextBytes(buffer); - return; - } - - _local = inst = CreateRandom(); - inst.NextBytes(buffer); - } - - private static global::System.Random CreateRandom() - { - int seed; - - lock (GLOBAL) - { - seed = GLOBAL.Next(); - } - - return new global::System.Random(seed); - } - } - } -} \ No newline at end of file diff --git a/Random/Application/System/Mapping/SystemRandomizersMapper.cs b/Random/Application/System/Mapping/SystemRandomizersMapper.cs new file mode 100644 index 0000000..cc23a62 --- /dev/null +++ b/Random/Application/System/Mapping/SystemRandomizersMapper.cs @@ -0,0 +1,53 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Collections.Generic; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Application.System.Mapping +{ + internal sealed class SystemRandomizersMapper + { + private readonly INumberRandomizer _intRandomizer; + private readonly ITypedRandomizer _doubleRandomizer; + private readonly IArrayRandomizer _byteRandomizer; + + public IRandomizer GetRandomizer(Type type) + { + switch (Type.GetTypeCode(type)) + { + case TypeCode.Int32: + return _intRandomizer; + case TypeCode.Double: + return _doubleRandomizer; + default: + { + if (type == typeof(byte[])) + { + return _byteRandomizer; + } + + throw new ArgumentException(); + } + } + } + + public IEnumerable GetAllRandomizers() + { + yield return _intRandomizer; + yield return _doubleRandomizer; + yield return _byteRandomizer; + } + + public SystemRandomizersMapper( + INumberRandomizer intRandomizer, + ITypedRandomizer doubleRandomizer, + IArrayRandomizer byteRandomizer) + { + _intRandomizer = intRandomizer; + _doubleRandomizer = doubleRandomizer; + _byteRandomizer = byteRandomizer; + } + } +} \ No newline at end of file diff --git a/Random/Application/System/Proxy/ByteArrayRandomProxy.cs b/Random/Application/System/Proxy/ByteArrayRandomProxy.cs new file mode 100644 index 0000000..77c2da6 --- /dev/null +++ b/Random/Application/System/Proxy/ByteArrayRandomProxy.cs @@ -0,0 +1,21 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Runtime.CompilerServices; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Application.System.Proxy +{ + internal sealed class ByteArrayRandomProxy : SystemRandomProxy, IArrayRandomizer + { + private static readonly Type VALUE_TYPE = typeof(byte[]); + + public Type ValueType => VALUE_TYPE; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Next(byte[] buffer) => GetRandom().NextBytes(buffer); + + public ByteArrayRandomProxy(global::System.Random random) : base(random) { } + } +} \ No newline at end of file diff --git a/Random/Application/System/Proxy/DoubleRandomProxy.cs b/Random/Application/System/Proxy/DoubleRandomProxy.cs new file mode 100644 index 0000000..fd447a6 --- /dev/null +++ b/Random/Application/System/Proxy/DoubleRandomProxy.cs @@ -0,0 +1,21 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Runtime.CompilerServices; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Application.System.Proxy +{ + internal sealed class DoubleRandomProxy : SystemRandomProxy, ITypedRandomizer + { + private static readonly Type VALUE_TYPE = typeof(double); + + public Type ValueType => VALUE_TYPE; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public double Next() => GetRandom().NextDouble(); + + public DoubleRandomProxy(global::System.Random random) : base(random) { } + } +} \ No newline at end of file diff --git a/Random/Application/System/Proxy/IntRandomProxy.cs b/Random/Application/System/Proxy/IntRandomProxy.cs new file mode 100644 index 0000000..c325673 --- /dev/null +++ b/Random/Application/System/Proxy/IntRandomProxy.cs @@ -0,0 +1,27 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Runtime.CompilerServices; +using Depra.Random.Domain.Randomizers; + +namespace Depra.Random.Application.System.Proxy +{ + internal sealed class IntRandomProxy : SystemRandomProxy, INumberRandomizer + { + private static readonly Type VALUE_TYPE = typeof(int); + + public Type ValueType => VALUE_TYPE; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int Next() => GetRandom().Next(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int Next(int maxExclusive) => GetRandom().Next(maxExclusive); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int Next(int minInclusive, int maxExclusive) => GetRandom().Next(minInclusive, maxExclusive); + + public IntRandomProxy(global::System.Random random) : base(random) { } + } +} \ No newline at end of file diff --git a/Random/Application/System/Proxy/SystemRandomProxy.cs b/Random/Application/System/Proxy/SystemRandomProxy.cs new file mode 100644 index 0000000..2b9564d --- /dev/null +++ b/Random/Application/System/Proxy/SystemRandomProxy.cs @@ -0,0 +1,17 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; + +namespace Depra.Random.Application.System.Proxy +{ + internal abstract class SystemRandomProxy + { + private readonly global::System.Random _random; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected global::System.Random GetRandom() => _random; + + protected SystemRandomProxy(global::System.Random random) => _random = random; + } +} \ No newline at end of file diff --git a/Random/Application/System/PseudoRandom.cs b/Random/Application/System/PseudoRandom.cs deleted file mode 100644 index 4f216aa..0000000 --- a/Random/Application/System/PseudoRandom.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright © 2022 Nikolay Melnikov. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using Depra.Random.Domain.Randomizers; - -namespace Depra.Random.Application.System -{ - /// - /// Decorator for , to support the contract. - /// - public sealed class PseudoRandom : global::System.Random, INumberRandomizer, ITypedRandomizer, - IArrayRandomizer - { - private static readonly Type[] VALUE_TYPES = {typeof(int), typeof(double), typeof(byte[])}; - - public IEnumerable ValueTypes => VALUE_TYPES; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - int ITypedRandomizer.Next() => base.Next(); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - int INumberRandomizer.Next(int maxExclusive) => base.Next(maxExclusive); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - int INumberRandomizer.Next(int minInclusive, int maxExclusive) => base.Next(minInclusive, maxExclusive); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - double ITypedRandomizer.Next() => NextDouble(); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - void IArrayRandomizer.Next(byte[] buffer) => NextBytes(buffer); - } -} \ No newline at end of file diff --git a/Random/Application/System/Randoms/ConcurrentPseudoRandom.cs b/Random/Application/System/Randoms/ConcurrentPseudoRandom.cs new file mode 100644 index 0000000..4c9e5be --- /dev/null +++ b/Random/Application/System/Randoms/ConcurrentPseudoRandom.cs @@ -0,0 +1,70 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +using System; + +namespace Depra.Random.Application.System.Randoms +{ + /// + /// A random number generator guaranteeing thread safety. + /// + public sealed class ConcurrentPseudoRandom : global::System.Random + { + private static readonly global::System.Random GLOBAL = new global::System.Random(); + + [ThreadStatic] private static global::System.Random _local; + + public override int Next() => Next(1, int.MaxValue); + + public override int Next(int maxExclusive) => Next(1, maxExclusive); + + public override int Next(int minInclusive, int maxExclusive) + { + var inst = _local; + if (inst != null) + { + return inst.Next(minInclusive, maxExclusive); + } + + _local = inst = CreateRandom(); + return inst.Next(minInclusive, maxExclusive); + } + + public override double NextDouble() + { + var inst = _local; + if (inst != null) + { + return inst.NextDouble(); + } + + _local = inst = CreateRandom(); + return inst.NextDouble(); + } + + public override void NextBytes(byte[] buffer) + { + var inst = _local; + if (inst != null) + { + inst.NextBytes(buffer); + return; + } + + _local = inst = CreateRandom(); + inst.NextBytes(buffer); + } + + private static global::System.Random CreateRandom() + { + int seed; + + lock (GLOBAL) + { + seed = GLOBAL.Next(); + } + + return new global::System.Random(seed); + } + } +} \ No newline at end of file diff --git a/Random/Application/System/CryptoRandomizer.cs b/Random/Application/System/Randoms/CryptoRandom.cs similarity index 63% rename from Random/Application/System/CryptoRandomizer.cs rename to Random/Application/System/Randoms/CryptoRandom.cs index b0b6f86..d01f02a 100644 --- a/Random/Application/System/CryptoRandomizer.cs +++ b/Random/Application/System/Randoms/CryptoRandom.cs @@ -2,41 +2,50 @@ // SPDX-License-Identifier: Apache-2.0 using System; -using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Security.Cryptography; using Depra.Random.Domain.Exceptions; -using Depra.Random.Domain.Randomizers; +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_0_OR_GREATER +#define CSHARP8_OR_GREATER +#endif -namespace Depra.Random.Application.System +namespace Depra.Random.Application.System.Randoms { /// /// A random number generator based on the . /// - public sealed class CryptoRandomizer : ITypedRandomizer, ITypedRandomizer, IArrayRandomizer, - IDisposable + public sealed class CryptoRandom : global::System.Random, IDisposable { - private static readonly Type[] VALUE_TYPES = {typeof(int), typeof(double), typeof(byte[])}; - private readonly RNGCryptoServiceProvider _rng; private bool _disposed; - public IEnumerable ValueTypes => VALUE_TYPES; + /// + /// Initializes a new instance of the class. + /// + public CryptoRandom() => _rng = new RNGCryptoServiceProvider(); /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. + /// This method will disregard whatever value is passed as seed and it's only implemented + /// in order to be fully backwards compatible with . /// - public CryptoRandomizer() => _rng = new RNGCryptoServiceProvider(); + /// The ignored seed. + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "ignoredSeed", + Justification = "Cannot remove this parameter as we implement the full API of System.Random")] + public CryptoRandom(int ignoredSeed) : this() { } - public int Next() + /// + public override int Next() { -#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_0_OR_GREATER +#if CSHARP8_OR_GREATER return RandomNumberGenerator.GetInt32(0, int.MaxValue); #else return GenerateInt32(); #endif } - public int Next(int maxExclusive) + /// + public override int Next(int maxExclusive) { if (maxExclusive < 0) { @@ -46,7 +55,8 @@ public int Next(int maxExclusive) return Next(0, maxExclusive); } - public int Next(int minInclusive, int maxExclusive) + /// + public override int Next(int minInclusive, int maxExclusive) { if (minInclusive > maxExclusive) { @@ -58,16 +68,18 @@ public int Next(int minInclusive, int maxExclusive) return minInclusive; } -#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_0_OR_GREATER +#if CSHARP8_OR_GREATER return RandomNumberGenerator.GetInt32(minInclusive, maxExclusive); #else return GenerateInt32(minInclusive, maxExclusive); #endif } - double ITypedRandomizer.Next() => GenerateUInt32() / (uint.MaxValue + 1.0); + /// + public override double NextDouble() => GenerateUInt32() / (uint.MaxValue + 1.0); - void IArrayRandomizer.Next(byte[] buffer) => _rng.GetBytes(buffer); + /// + public override void NextBytes(byte[] buffer) => _rng.GetBytes(buffer); /// /// Gets one random unsigned 32bit integer. @@ -82,8 +94,8 @@ public int Next(int minInclusive, int maxExclusive) /// /// Gets one random signed 32bit integer in range. /// - private int GenerateInt32(int minInclusive, int maxExclusive) => (int) Math.Floor(minInclusive + - ((double) maxExclusive - minInclusive) * (this as ITypedRandomizer).Next()); + private int GenerateInt32(int minInclusive, int maxExclusive) => + (int) Math.Floor(minInclusive + ((double) maxExclusive - minInclusive) * NextDouble()); /// /// Gets one random byte array. @@ -96,7 +108,7 @@ private byte[] GenerateBytes(int size) return randomBytes; } - ~CryptoRandomizer() => Dispose(false); + ~CryptoRandom() => Dispose(false); /// public void Dispose() diff --git a/Random/Domain/Exceptions/RandomizerForTypeNotRegisteredException.cs b/Random/Domain/Exceptions/RandomizerForTypeNotRegisteredException.cs index 4aa0075..40c595a 100644 --- a/Random/Domain/Exceptions/RandomizerForTypeNotRegisteredException.cs +++ b/Random/Domain/Exceptions/RandomizerForTypeNotRegisteredException.cs @@ -1,3 +1,6 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + using System; using System.Reflection; diff --git a/Random/Domain/Exceptions/ThrowHelper.Partial.cs b/Random/Domain/Exceptions/ThrowHelper.Partial.cs index 03c8968..e359ee9 100644 --- a/Random/Domain/Exceptions/ThrowHelper.Partial.cs +++ b/Random/Domain/Exceptions/ThrowHelper.Partial.cs @@ -1,3 +1,6 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + namespace Depra.Random.Domain.Exceptions { internal static partial class Throw diff --git a/Random/Domain/Exceptions/ThrowHelper.cs b/Random/Domain/Exceptions/ThrowHelper.cs index 882736f..2ce00a0 100644 --- a/Random/Domain/Exceptions/ThrowHelper.cs +++ b/Random/Domain/Exceptions/ThrowHelper.cs @@ -3,7 +3,6 @@ using System; using System.Reflection; - #if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_0_OR_GREATER || NET5_0_OR_GREATER using System.Diagnostics.CodeAnalysis; #define CSHARP8_OR_GREATER diff --git a/Random/Domain/Extensions/RandomizerExtensions.Int64.cs b/Random/Domain/Extensions/RandomizerExtensions.Int64.cs index d367c30..2bcdcf4 100644 --- a/Random/Domain/Extensions/RandomizerExtensions.Int64.cs +++ b/Random/Domain/Extensions/RandomizerExtensions.Int64.cs @@ -3,7 +3,6 @@ using Depra.Random.Domain.Exceptions; using Depra.Random.Domain.Randomizers; -using Depra.Random.Extensions; namespace Depra.Random.Domain.Extensions { diff --git a/Random/Domain/Randomizers/IArrayRandomizer.cs b/Random/Domain/Randomizers/IArrayRandomizer.cs index f89c03f..f8ba6a1 100644 --- a/Random/Domain/Randomizers/IArrayRandomizer.cs +++ b/Random/Domain/Randomizers/IArrayRandomizer.cs @@ -1,3 +1,6 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + namespace Depra.Random.Domain.Randomizers { public interface IArrayRandomizer : IRandomizer diff --git a/Random/Domain/Randomizers/INumberRandomizer.cs b/Random/Domain/Randomizers/INumberRandomizer.cs index 979a141..b942c65 100644 --- a/Random/Domain/Randomizers/INumberRandomizer.cs +++ b/Random/Domain/Randomizers/INumberRandomizer.cs @@ -1,3 +1,6 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + namespace Depra.Random.Domain.Randomizers { public interface INumberRandomizer : ITypedRandomizer diff --git a/Random/Domain/Randomizers/IRandomizer.cs b/Random/Domain/Randomizers/IRandomizer.cs index 10f0808..95d12f6 100644 --- a/Random/Domain/Randomizers/IRandomizer.cs +++ b/Random/Domain/Randomizers/IRandomizer.cs @@ -1,10 +1,12 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + using System; -using System.Collections.Generic; namespace Depra.Random.Domain.Randomizers { public interface IRandomizer { - IEnumerable ValueTypes { get; } + Type ValueType { get; } } } \ No newline at end of file diff --git a/Random/Domain/Randomizers/IRandomizerCollection.cs b/Random/Domain/Randomizers/IRandomizerCollection.cs index c189a0c..bad47e0 100644 --- a/Random/Domain/Randomizers/IRandomizerCollection.cs +++ b/Random/Domain/Randomizers/IRandomizerCollection.cs @@ -1,3 +1,6 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + using System; using System.Collections.Generic; diff --git a/Random/Domain/Randomizers/ITypedRandomizer.cs b/Random/Domain/Randomizers/ITypedRandomizer.cs index 6f004f9..95342a3 100644 --- a/Random/Domain/Randomizers/ITypedRandomizer.cs +++ b/Random/Domain/Randomizers/ITypedRandomizer.cs @@ -1,3 +1,6 @@ +// Copyright © 2022 Nikolay Melnikov. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + namespace Depra.Random.Domain.Randomizers { public interface ITypedRandomizer : IRandomizer