private void CountTracking() { int reportEvery = 10000; Shielded<int> lastReport = new Shielded<int>(0); Shielded<DateTime> lastTime = new Shielded<DateTime>(DateTime.UtcNow); Shield.Conditional(() => _processed >= lastReport + reportEvery, () => { DateTime newNow = DateTime.UtcNow; int count = _processed; int speed = (count - lastReport) * 1000 / (int)newNow.Subtract(lastTime).TotalMilliseconds; lastTime.Assign(newNow); lastReport.Modify((ref int n) => n += reportEvery); int sc = _subscribeCount; int ptc = _processTestCount; int pbc = _processBodyCount; Shield.SideEffect(() => { Console.WriteLine( "{0} at {1} item/s, stats ( {2}, {3}, {4} )", count, speed, sc, ptc, pbc); }); return true; }); }
public void Run() { Console.WriteLine("Queue test..."); ProcessorSlot.Set(Environment.ProcessorCount - 1); CountTracking(); Subscribe(); var maxQueueCount = new Shielded<int>(); Shield.Conditional(() => _queue.Count > maxQueueCount, () => { maxQueueCount.Assign(_queue.Count); return true; }); // create ItemCount items and push them in the queue. Stopwatch stopwatch = new Stopwatch(); var items = Enumerable.Range(1, ItemCount).Select( i => new Item() { Id = Guid.NewGuid(), Code = i, Amount = 100m * i }).ToArray(); stopwatch.Start(); for (int i = 0; i < ItemCount / 100; i++) { Shield.InTransaction(() => { for (int j = 0; j < 100; j++) _queue.Append(items[i*100 + j]); }); } Console.WriteLine("..all items added, waiting."); _barrier.SignalAndWait(); var time = stopwatch.ElapsedMilliseconds; Console.WriteLine(" -- completed in {0} ms, with {1} max queue count.", time, maxQueueCount.Read); }
public static void TreeTest() { int numTasks = 100000; int reportEvery = 1000; ShieldedTree<Guid, TreeItem> tree = new ShieldedTree<Guid, TreeItem>(); int transactionCount = 0; Shielded<int> lastReport = new Shielded<int>(0); Shielded<int> countComplete = new Shielded<int>(0); // Shielded<DateTime> lastTime = new Shielded<DateTime>(DateTime.UtcNow); // // Shield.Conditional(() => countComplete >= lastReport + reportEvery, () => // { // DateTime newNow = DateTime.UtcNow; // int speed = (countComplete - lastReport) * 1000 / (int)newNow.Subtract(lastTime).TotalMilliseconds; // lastTime.Assign(newNow); // lastReport.Modify((ref int n) => n += reportEvery); // int count = countComplete; // Shield.SideEffect(() => // { // Console.Write("\n{0} at {1} item/s", count, speed); // } // ); // return true; // } // ); 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) { ShieldedDict<Guid, TreeItem> dict = new ShieldedDict<Guid, TreeItem>(); transactionCount = 0; Shield.InTransaction(() => { countComplete.Assign(0); lastReport.Assign(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 = 4; int numItems = 200000; // for some reason, if this is replaced with ShieldedDict, KeyAlreadyPresent // exception is thrown. under one key you can then find an entity which does // not have that key. complete mystery. var tree = new ShieldedDict<Guid, TreeItem>(); var barrier = new Barrier(numThreads + 1); int reportEvery = 10000; Shielded<int> lastReport = new Shielded<int>(0); Shielded<DateTime> lastTime = new Shielded<DateTime>(DateTime.UtcNow); Shield.Conditional(() => tree.Count >= lastReport + reportEvery, () => { DateTime newNow = DateTime.UtcNow; int count = tree.Count; int speed = (count - lastReport) * 1000 / (int)newNow.Subtract(lastTime).TotalMilliseconds; lastTime.Assign(newNow); lastReport.Modify((ref int n) => n += reportEvery); Shield.SideEffect(() => { Console.Write("\n{0} at {1} item/s", count, speed); }); return true; }); TreeItem x = new TreeItem(); _timer = new Stopwatch(); _timer.Start(); var time = _timer.ElapsedMilliseconds; foreach (var k in Enumerable.Repeat(1, numItems)) Shield.InTransaction(() => x.Id); time = _timer.ElapsedMilliseconds - time; Console.WriteLine("1 read 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(); }); } foreach (var i in Enumerable.Range(0, numItems)) { var item1 = new TreeItem(); bags[i % numThreads].Add(() => Shield.InTransaction(() => { tree.Add(item1.Id, item1); })); } 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 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(() => x.Id); time = _timer.ElapsedMilliseconds - time; Console.WriteLine("1 read transactions in {0} ms.", time); }
public static void BetShopPoolTest() { int numThreads = 3; int numTickets = 200000; int numEvents = 100; var barrier = new Barrier(2); var betShop = new BetShop(numEvents); var randomizr = new Random(); int reportEvery = 10000; //Shielded<int> nextReport = new Shielded<int>(reportEvery); //Shield.Conditional(() => betShop.TicketCount >= nextReport, () => //{ // nextReport.Modify((ref int n) => n += reportEvery); // Shield.SideEffect(() => // { // Console.Write(" {0}..", betShop.TicketCount); // }); // return true; //}); Shielded<int> lastReport = new Shielded<int>(0); Shielded<DateTime> lastTime = new Shielded<DateTime>(DateTime.UtcNow); Shield.Conditional(() => betShop.Tickets.Count >= lastReport + reportEvery, () => { DateTime newNow = DateTime.UtcNow; int count = betShop.Tickets.Count; int speed = (count - lastReport) * 1000 / (int)newNow.Subtract(lastTime).TotalMilliseconds; lastTime.Assign(newNow); lastReport.Modify((ref int n) => n += reportEvery); Shield.SideEffect(() => { Console.Write("\n{0} at {1} item/s", count, speed); }); return true; }); 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) a(); }); } var complete = new Shielded<int>(); Shield.Conditional(() => complete == numTickets, () => { barrier.SignalAndWait(); return false; }); foreach (var i in Enumerable.Range(0, numTickets)) { decimal payIn = (randomizr.Next(10) + 1m) * 1; int event1Id = randomizr.Next(numEvents) + 1; int event2Id = randomizr.Next(numEvents) + 1; int event3Id = randomizr.Next(numEvents) + 1; int offer1Ind = randomizr.Next(3); int offer2Ind = randomizr.Next(3); int offer3Ind = randomizr.Next(3); bags[i % numThreads].Add(() => Shield.InTransaction(() => { var offer1 = betShop.Events[event1Id].Read.BetOffers[offer1Ind]; var offer2 = betShop.Events[event2Id].Read.BetOffers[offer2Ind]; var offer3 = betShop.Events[event3Id].Read.BetOffers[offer3Ind]; betShop.BuyTicket(payIn, offer1, offer2, offer3); complete.Commute((ref int n) => n++); })); } _timer = new Stopwatch(); _timer.Start(); for (int i = 0; i < numThreads; i++) threads[i].Start(); barrier.SignalAndWait(); var time = _timer.ElapsedMilliseconds; var totalCorrect = betShop.VerifyTickets(); Console.WriteLine(" {0} ms with {1} tickets paid in and is {2}.", time, betShop.Tickets.Count, totalCorrect ? "correct" : "incorrect"); }
/// <summary> /// Creates a BetShop, and tries to buy a large number of random tickets. Afterwards it /// checks that the rule limiting same ticket winnings is not violated. /// </summary> public static void BetShopTest() { int numEvents = 100; var betShop = new BetShop(numEvents); var randomizr = new Random(); int reportEvery = 1000; //Shielded<int> nextReport = new Shielded<int>(reportEvery); //Shield.Conditional(() => betShop.TicketCount >= nextReport, () => //{ // nextReport.Modify((ref int n) => n += reportEvery); // Shield.SideEffect(() => // { // Console.Write(" {0}..", betShop.TicketCount); // }); // return true; //}); Shielded<int> lastReport = new Shielded<int>(0); Shielded<DateTime> lastTime = new Shielded<DateTime>(DateTime.UtcNow); var reportingCond = Shield.Conditional(() => betShop.Tickets.Count >= lastReport + reportEvery, () => { DateTime newNow = DateTime.UtcNow; int count = betShop.Tickets.Count; int speed = (count - lastReport) * 1000 / (int)newNow.Subtract(lastTime).TotalMilliseconds; lastTime.Assign(newNow); lastReport.Modify((ref int n) => n += reportEvery); Shield.SideEffect(() => { Console.Write("\n{0} at {1} item/s", count, speed); }); return true; }); var time = mtTest("bet shop w/ " + numEvents, 50000, i => { decimal payIn = (randomizr.Next(10) + 1m) * 1; int event1Id = randomizr.Next(numEvents) + 1; int event2Id = randomizr.Next(numEvents) + 1; int event3Id = randomizr.Next(numEvents) + 1; int offer1Ind = randomizr.Next(3); int offer2Ind = randomizr.Next(3); int offer3Ind = randomizr.Next(3); return Task.Factory.StartNew(() => Shield.InTransaction(() => { var offer1 = betShop.Events[event1Id].Read.BetOffers[offer1Ind]; var offer2 = betShop.Events[event2Id].Read.BetOffers[offer2Ind]; var offer3 = betShop.Events[event3Id].Read.BetOffers[offer3Ind]; betShop.BuyTicket(payIn, offer1, offer2, offer3); })); }); Shield.CancelConditional(reportingCond); var totalCorrect = betShop.VerifyTickets(); Console.WriteLine(" {0} ms with {1} tickets paid in and is {2}.", time, betShop.Tickets.Count, totalCorrect ? "correct" : "incorrect"); }
public void RaceTest() { var x = new Shielded<int>(); int transactionCount = 0; Task.WaitAll( Enumerable.Range(1, 100).Select(i => Task.Factory.StartNew(() => { bool committed = false; try { Shield.InTransaction(() => { Shield.SideEffect(() => { committed = true; }); Interlocked.Increment(ref transactionCount); int a = x; Thread.Sleep(5); x.Assign(a + i); if (i == 100) throw new InvalidOperationException(); }); Assert.AreNotEqual(100, i); Assert.IsTrue(committed); } catch { Assert.AreEqual(100, i); Assert.IsFalse(committed); } }, TaskCreationOptions.LongRunning)).ToArray()); Assert.AreEqual(4950, x); // just to confirm validity of test! not really a fail if this fails. Assert.Greater(transactionCount, 100); }