public static void TreeTest() { int numTasks = 100000; var tree = new ShieldedTreeNc<Guid, TreeItem>(); int transactionCount = 0; Shielded<int> lastReport = new Shielded<int>(0); Shielded<int> countComplete = new Shielded<int>(0); if (true) { var treeTime = mtTest("tree", numTasks, i => { return Task.Factory.StartNew(() => { var item1 = new TreeItem(); Shield.InTransaction(() => { //Interlocked.Increment(ref transactionCount); tree.Add(item1.Id, item1); // countComplete.Commute((ref int c) => c++); } ); } ); } ); Guid? previous = null; bool correct = true; Shield.InTransaction(() => { int count = 0; foreach (var item in tree) { count++; if (previous != null && previous.Value.CompareTo(item.Key) > 0) { correct = false; break; } previous = item.Key; } correct = correct && (count == numTasks); } ); Console.WriteLine("\n -- {0} ms with {1} iterations and is {2}.", treeTime, transactionCount, correct ? "correct" : "incorrect"); } if (true) { var dict = new ShieldedDictNc<Guid, TreeItem>(); transactionCount = 0; Shield.InTransaction(() => { countComplete.Value = 0; lastReport.Value = 0; } ); var time = mtTest("dictionary", numTasks, i => { return Task.Factory.StartNew(() => { var item1 = new TreeItem(); Shield.InTransaction(() => { //Interlocked.Increment(ref transactionCount); dict[item1.Id] = item1; // countComplete.Commute((ref int c) => c++); } ); } ); } ); Console.WriteLine("\n -- {0} ms with {1} iterations. Not sorted.", time, transactionCount); } if (true) { ConcurrentDictionary<Guid, TreeItem> dict = new ConcurrentDictionary<Guid, TreeItem>(); var time = mtTest("ConcurrentDictionary", numTasks, i => { return Task.Factory.StartNew(() => { var item1 = new TreeItem(); dict[item1.Id] = item1; } ); } ); Console.WriteLine("\n -- {0} ms with {1} iterations. Not sorted.", time, numTasks); } }
public static void TreePoolTest() { int numThreads = Environment.ProcessorCount; int numItems = 500000; var tree = new ShieldedTreeNc<Guid, TreeItem>(); var barrier = new Barrier(numThreads + 1); var counter = 0; int reportEvery = 10000; var lastReport = 0; long time; TreeItem x = new TreeItem(); _timer = new Stopwatch(); _timer.Start(); time = _timer.ElapsedMilliseconds; foreach (var k in Enumerable.Repeat(1, numItems)) Shield.InTransaction(() => { var a = x.Id; }); time = _timer.ElapsedMilliseconds - time; Console.WriteLine("Empty transactions in {0} ms.", time); var bags = new List<Action>[numThreads]; var threads = new Thread[numThreads]; for (int i = 0; i < numThreads; i++) { var bag = bags[i] = new List<Action>(); threads[i] = new Thread(() => { foreach (var a in bag) { try { a(); } catch { Console.Write(" * "); } } barrier.SignalAndWait(); }); } var lastTime = _timer.ElapsedMilliseconds; foreach (var i in Enumerable.Range(0, numItems)) { var item1 = new TreeItem(); bags[i % numThreads].Add(() => Shield.InTransaction(() => { tree.Add(item1.Id, item1); Shield.SideEffect(() => { var last = lastReport; var count = Interlocked.Increment(ref counter); var newNow = _timer.ElapsedMilliseconds; if (count > last + reportEvery && Interlocked.CompareExchange(ref lastReport, last + reportEvery, last) == last) { var speed = reportEvery * 1000 / (newNow - lastTime); lastTime = newNow; // risky, but safe ;) Console.Write("\n{0} at {1} item/s", last + reportEvery, speed); } }); })); } lastTime = _timer.ElapsedMilliseconds; for (int i = 0; i < numThreads; i++) threads[i].Start(); barrier.SignalAndWait(); time = _timer.ElapsedMilliseconds; Console.WriteLine(" {0} ms.", time); Console.WriteLine("\nReading sequentially..."); time = _timer.ElapsedMilliseconds; var keys = Shield.InTransaction(() => tree.Keys); time = _timer.ElapsedMilliseconds - time; Console.WriteLine("Keys read in {0} ms.", time); time = _timer.ElapsedMilliseconds; Shield.InTransaction(() => { foreach (var kvp in tree) x = kvp.Value; }); time = _timer.ElapsedMilliseconds - time; Console.WriteLine("Items read by enumerator in {0} ms.", time); time = _timer.ElapsedMilliseconds; Shield.InTransaction(() => { foreach (var kvp in tree.OrderBy(kvp => kvp.Key)) x = kvp.Value; }); time = _timer.ElapsedMilliseconds - time; Console.WriteLine("Items read by sorted enumerator in {0} ms.", time); time = _timer.ElapsedMilliseconds; Shield.InTransaction(() => { foreach (var k in keys) x = tree[k]; }); time = _timer.ElapsedMilliseconds - time; Console.WriteLine("Items read by key in one trans in {0} ms.", time); time = _timer.ElapsedMilliseconds; foreach (var k in keys) x = tree[k]; time = _timer.ElapsedMilliseconds - time; Console.WriteLine("Items read by key separately in {0} ms.", time); time = _timer.ElapsedMilliseconds; keys.AsParallel().ForAll(k => x = tree[k]); time = _timer.ElapsedMilliseconds - time; Console.WriteLine("Items read by key in parallel in {0} ms.", time); time = _timer.ElapsedMilliseconds; foreach (var k in Enumerable.Repeat(1, numItems)) Shield.InTransaction(() => { var a = x.Id; }); time = _timer.ElapsedMilliseconds - time; Console.WriteLine("Empty transactions in {0} ms.", time); }