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(); }