Example #1
0
        public static void Main(string[] args)
        {
            /*
             * It's always good to call StartEarly.StartFillingEntropyPools() as early as possible when the application is launched.
             * But during benchmarking performance below, then it's not really fair to let them start early.
             */
            Benchmark("SystemRng", bytesBuffer =>
            {
                var mySystemRngCryptoServiceProvider = new SystemRng();
                mySystemRngCryptoServiceProvider.GetBytes(bytesBuffer);
                return(bytesBuffer);
            });
            Benchmark("RNGCryptoServiceProvider", bytesBuffer =>
            {
                using (var rng = RandomNumberGenerator.Create())
                {
                    rng.GetBytes(bytesBuffer);
                }

                return(bytesBuffer);
            });

            /*
             * Test each of the ThreadedSeedGeneratorRng and ThreadSchedulerRng prior to doing SafeRandom
             * or FastRandom, because otherwise, SafeRandom will create static instances of them, which race, etc
             * thus throwing off my results.
             */
            Benchmark("ThreadedSeedGeneratorRng", bytesBuffer =>
            {
                var myThreadedSeedGeneratorRng = new ThreadedSeedGeneratorRng();
                myThreadedSeedGeneratorRng.GetBytes(bytesBuffer);
                return(bytesBuffer);
            });
            SleepForPools(3000);
            Benchmark("ThreadedSeedGenerator(fast)", bytesBuffer =>
            {
                var myThreadedSeedGenerator = new ThreadedSeedGenerator();
                var seed = myThreadedSeedGenerator.GenerateSeed(RandBytesLength, true);
                return(seed);
            });
            Benchmark("ThreadedSeedGenerator(slow)", bytesBuffer =>
            {
                var myThreadedSeedGenerator = new ThreadedSeedGenerator();
                var seed = myThreadedSeedGenerator.GenerateSeed(RandBytesLength, false);
                return(seed);
            });
            Benchmark("ThreadSchedulerRNG(slow)", bytesBuffer =>
            {
                var threadSchedulerRng = new ThreadSchedulerRng();
                threadSchedulerRng.GetBytes(bytesBuffer);
                return(bytesBuffer);
            });

            SleepForPools(15000);

            Benchmark(
                "SafeRandom",
                bytesBuffer => SafeRandom.StaticInstance.GetBytes(bytesBuffer.Length));

            SleepForPools(15000);

            Benchmark(
                "FastRandom",
                bytesBuffer => FastRandom.StaticInstance.GetBytes(bytesBuffer.Length));

            SleepForPools(15000);

            Console.WriteLine("");

            PresentResults();

            Console.WriteLine("");
            Console.Error.WriteLine("Finished");
            Console.Out.Flush();
            Console.ReadKey();
        }
Example #2
0
        public static void Main(string[] args)
        {
            // It's always good to StartFillingEntropyPools as early as possible when the application is launched.
            // But if I'm benchmarking performance below, then it's not really fair to let them start early.
            // StartEarly.StartFillingEntropyPools();

            DateTime     before;
            DateTime     after;
            RandomResult result;

            const int randBytesLength = 8 * 1024;

            var results = new List <RandomResult>();

            //AllZeros
            result = new RandomResult {
                AlgorithmName = "AllZeros"
            };
            before = DateTime.Now;
            var randBytes = new byte[randBytesLength];

            after                   = DateTime.Now;
            result.TimeSpan         = after - before;
            result.CompressionRatio = CompressionUtility.GetCompressionRatio(randBytes).Result;
            results.Add(result);

            //SystemRng
            result = new RandomResult {
                AlgorithmName = "SystemRng"
            };
            Console.Write(result.AlgorithmName + " ");
            before = DateTime.Now;
            var mySystemRngCryptoServiceProvider = new SystemRng();

            mySystemRngCryptoServiceProvider.GetBytes(randBytes);
            after                   = DateTime.Now;
            result.TimeSpan         = after - before;
            result.CompressionRatio = CompressionUtility.GetCompressionRatio(randBytes).Result;
            results.Add(result);
            Console.WriteLine((after - before).ToString());

            //RNGCryptoServiceProvider
            result = new RandomResult();
            result.AlgorithmName = "RNGCryptoServiceProvider";
            Console.Write(result.AlgorithmName + " ");
            before = DateTime.Now;
            using (var rng = RandomNumberGenerator.Create())
            {
                rng.GetBytes(randBytes);
            }
            after                   = DateTime.Now;
            result.TimeSpan         = after - before;
            result.CompressionRatio = CompressionUtility.GetCompressionRatio(randBytes).Result;
            results.Add(result);
            Console.WriteLine((after - before).ToString());

            //ThreadedSeedGeneratorRng
            result = new RandomResult();
            result.AlgorithmName = "ThreadedSeedGeneratorRng";
            Console.Write(result.AlgorithmName + " ");
            before = DateTime.Now;
            var myThreadedSeedGeneratorRng = new ThreadedSeedGeneratorRng();

            myThreadedSeedGeneratorRng.GetBytes(randBytes);
            after                   = DateTime.Now;
            result.TimeSpan         = after - before;
            result.CompressionRatio = CompressionUtility.GetCompressionRatio(randBytes).Result;
            results.Add(result);
            Console.WriteLine((after - before).ToString());
            Console.Write("Sleeping to allow pool to fill...");
            Thread.Sleep(3000); // Should be enough time for its pool to fill up, so it won't slow down next:
            Console.WriteLine("  Done.");

            //ThreadedSeedGenerator(fast)
            result = new RandomResult();
            result.AlgorithmName = "ThreadedSeedGenerator(fast)";
            Console.Write(result.AlgorithmName + " ");
            var myThreadedSeedGenerator = new ThreadedSeedGenerator();

            Array.Clear(randBytes, 0, randBytesLength);
            before                  = DateTime.Now;
            randBytes               = myThreadedSeedGenerator.GenerateSeed(randBytesLength, true);
            after                   = DateTime.Now;
            result.TimeSpan         = after - before;
            result.CompressionRatio = CompressionUtility.GetCompressionRatio(randBytes).Result;
            results.Add(result);
            Console.WriteLine((after - before).ToString());

            //ThreadedSeedGenerator(slow)
            result = new RandomResult();
            result.AlgorithmName = "ThreadedSeedGenerator(slow)";
            Console.Write(result.AlgorithmName + " ");
            Array.Clear(randBytes, 0, randBytesLength);
            before                  = DateTime.Now;
            randBytes               = myThreadedSeedGenerator.GenerateSeed(randBytesLength, false);
            after                   = DateTime.Now;
            result.TimeSpan         = after - before;
            result.CompressionRatio = CompressionUtility.GetCompressionRatio(randBytes).Result;
            results.Add(result);
            Console.WriteLine((after - before).ToString());

            //ThreadSchedulerRNG(slow)
            result = new RandomResult();
            result.AlgorithmName = "ThreadSchedulerRng";
            Console.Write(result.AlgorithmName + " ");
            before = DateTime.Now;
            var myThreadSchedulerRNG = new ThreadSchedulerRng();

            myThreadSchedulerRNG.GetBytes(randBytes);
            after                   = DateTime.Now;
            result.TimeSpan         = after - before;
            result.CompressionRatio = CompressionUtility.GetCompressionRatio(randBytes).Result;
            results.Add(result);
            Console.WriteLine((after - before).ToString());

            const int numResults = 14;

            Console.Write("ticks bit positions ");
            before = DateTime.Now;
            var ticksResults      = new RandomResult[numResults];
            var ticksResultsBytes = new byte[numResults][];

            for (var i = 0; i < numResults; i++)
            {
                ticksResults[i] = new RandomResult
                {
                    AlgorithmName = "ticks bit #" + i.ToString().PadLeft(2)
                };
                ticksResultsBytes[i] = new byte[randBytesLength];
            }
            for (var i = 0; i < randBytesLength; i++)
            {
                for (var j = 0; j < 8; j++)
                {
                    var ticks = DateTime.Now.Ticks;
                    for (var bitPos = 0; bitPos < numResults; bitPos++)
                    {
                        ticksResultsBytes[bitPos][i] <<= 1;
                        ticksResultsBytes[bitPos][i]  += (byte)(ticks % 2);
                        ticks >>= 1;
                    }
                    Thread.Sleep(1);
                }
            }
            after = DateTime.Now;
            for (var i = 0; i < numResults; i++)
            {
                ticksResults[i].TimeSpan         = after - before;
                ticksResults[i].CompressionRatio = CompressionUtility.GetCompressionRatio(ticksResultsBytes[i]).Result;
                results.Add(ticksResults[i]);
            }
            Console.WriteLine((after - before).ToString());
            Console.Write("Sleeping to allow pool to fill...");
            Thread.Sleep(15000); // Should be enough time for its pool to fill up, so it won't slow down next:
            Console.WriteLine("  Done.");

            // I want to test each of the ThreadedSeedGeneratorRng and ThreadSchedulerRng prior to doing TinHatRandom
            // or TinHatURandom, because otherwise, TinHatRandom will create static instances of them, which race, etc.
            // thus throwing off my benchmark results.

            //SafeRandom
            result = new RandomResult {
                AlgorithmName = "SafeRandom"
            };
            Console.Write(result.AlgorithmName + " ");
            before                  = DateTime.Now;
            randBytes               = SafeRandom.StaticInstance.GetBytes(randBytes.Length);
            after                   = DateTime.Now;
            result.TimeSpan         = after - before;
            result.CompressionRatio = CompressionUtility.GetCompressionRatio(randBytes).Result;
            results.Add(result);
            Console.WriteLine((after - before).ToString());
            Console.Write("Sleeping to allow pool to fill...");
            Thread.Sleep(15000); // Should be enough time for its pool to fill up, so it won't slow down next:
            Console.WriteLine("  Done.");

            result = new RandomResult {
                AlgorithmName = "FastRandom"
            };
            Console.Write(result.AlgorithmName + " ");
            before                  = DateTime.Now;
            randBytes               = FastRandom.StaticInstance.GetBytes(randBytes.Length);
            after                   = DateTime.Now;
            result.TimeSpan         = after - before;
            result.CompressionRatio = CompressionUtility.GetCompressionRatio(randBytes).Result;
            results.Add(result);
            Console.WriteLine((after - before).ToString());
            Console.Write("Sleeping to allow pool to fill...");
            Thread.Sleep(15000); // Should be enough time for its pool to fill up, so it won't slow down next:
            Console.WriteLine("  Done.");

            Console.WriteLine("");

            var maxCompressionRatio = double.MinValue;
            var minCompressionRatio = double.MaxValue;
            var longestName         = 0;

            foreach (var theResult in results)
            {
                if (theResult.AlgorithmName.Length > longestName)
                {
                    longestName = theResult.AlgorithmName.Length;
                }
                if (theResult.CompressionRatio < minCompressionRatio)
                {
                    minCompressionRatio = theResult.CompressionRatio;
                }
                if (theResult.CompressionRatio > maxCompressionRatio)
                {
                    maxCompressionRatio = theResult.CompressionRatio;
                }
            }
            Console.WriteLine("AlgorithmName".PadLeft(longestName) + " : bits per bit : elapsed sec : effective rate");
            foreach (var theResult in results)
            {
                var bitsPerBit = (theResult.CompressionRatio - minCompressionRatio) /
                                 (maxCompressionRatio - minCompressionRatio);
                double byteRate;
                string byteRateString;
                if (theResult.TimeSpan.TotalSeconds == 0)
                {
                    if (theResult.CompressionRatio == minCompressionRatio)
                    {
                        byteRateString = "0";
                    }
                    else
                    {
                        byteRateString = "infinity";
                    }
                }
                else
                {
                    byteRate = bitsPerBit * randBytesLength / theResult.TimeSpan.TotalSeconds;
                    if (byteRate > 1000000)
                    {
                        byteRateString = (byteRate / 1000000).ToString("F2") + " MiB/sec";
                    }
                    else if (byteRate > 1000)
                    {
                        byteRateString = (byteRate / 1000).ToString("F2") + " KiB/sec";
                    }
                    else
                    {
                        byteRateString = byteRate.ToString("F2") + " B/sec";
                    }
                }
                Console.WriteLine(theResult.AlgorithmName.PadLeft(longestName) + " : " +
                                  bitsPerBit.ToString("0.000").PadLeft(12) + " : " +
                                  theResult.TimeSpan.TotalSeconds.ToString("0.000").PadLeft(11) + " : " +
                                  byteRateString.PadLeft(14));
            }

            Console.WriteLine("");
            Console.Error.WriteLine("Finished");
            Console.Out.Flush();
            Console.ReadKey();
        }