Ejemplo n.º 1
0
        public ReadWriteHelper(bool supportRecursion)
        {
            //Debug.WriteLine("Constructing: "+this.ToString());

            RecursionPolicy = supportRecursion
                                ? LockRecursionPolicy.SupportsRecursion
                                : LockRecursionPolicy.NoRecursion;

            ContextPool = OptimisticArrayObjectPool.Create <object>();

            Action <ReaderWriterLockTracker> recycle = null;

#if DEBUG
            recycle = rwlt => Debug.Assert(rwlt.Lock.IsLockFree());
#endif
            // ReSharper disable once ExpressionIsAlwaysNull
            LockPool = new ConcurrentQueueObjectPool <ReaderWriterLockTracker>(Factory, recycle, d => d.Dispose(), 1000);
        }
    static void Main()
    {
        Console.Write("Initializing...");

        var sb     = new StringBuilder();
        var report = new ConsoleReport <object>(sb);

        /*
         * Notes:
         * 1) ConcurrentBag seems to be PAINFULLY slow compared to ConcurrentQueue.
         * 2) The speed gap between an optimistic array and its interlocked couterpart grows large very quickly (as expected).
         * 3) A sync locked Queue is faster than a sync locked LinkedList.
         * 4) ConcurrentQueue seems to be the overall winner when dealing with pools larger than 100 but is the clear loser for very small sizes.
         */

        // Start with a baseline...
        //report.AddBenchmark("QueueObjectPool", // Note, that this one isn't far off from the following in peformance.
        //	count => () => QueueObjectPool.Create<object>((int)count * 2));

        report.AddBenchmark("Microsoft.Extensions.ObjectPool.DefaultObjectPool",
                            count => () => new DefaultObjectPool <object>(() => new object(), (int)count * 2));

        report.AddBenchmark("ConcurrentQueueObjectPoolSlim",
                            count => () => ConcurrentQueueObjectPoolSlim.Create <object>((int)count * 2));

        report.AddBenchmark("ConcurrentQueueObjectPool",
                            count => () => ConcurrentQueueObjectPool.Create <object>((int)count * 2));

        //report.AddBenchmark("ConcurrentStackObjectPool",
        //	count => () => ConcurrentStackObjectPool.Create<object>((int)count * 2));

        report.AddBenchmark("OptimisticArrayObjectPool",
                            count => () => OptimisticArrayObjectPool.Create <object>((int)count * 2));

        // Is ineveitably slower than the above but should be enabled for testing code changes.
        report.AddBenchmark("InterlockedArrayObjectPool",
                            count => () => InterlockedArrayObjectPool.Create <object>((int)count * 2));

        report.Pretest(200, 200);         // Run once through first to scramble/warm-up initial conditions.

        Console.SetCursorPosition(0, Console.CursorTop);

        const int loopMultiple = 12;

        report.Test(4, 8 * loopMultiple);
        report.Test(10, 8 * loopMultiple);
        report.Test(50, 12 * loopMultiple);
        report.Test(100, 16 * loopMultiple);
        report.Test(250, 32 * loopMultiple);
        //report.Test(2000, 64 * loopMultiple);

        File.WriteAllText("./BenchmarkResult.txt", sb.ToString());
        using (var fs = File.OpenWrite("./BenchmarkResult.csv"))
            using (var sw = new StreamWriter(fs))
                using (var csv = new CsvWriter(sw))
                {
                    csv.WriteRow(report.ResultLabels);
                    csv.WriteRows(report.Results);
                }

        Console.Beep();
        Console.WriteLine("(press any key when finished)");
        Console.ReadKey();
    }