public void Bid_Heap_Latency() { const int size = 1024 * 1024; var arr1 = new Quote[128 * 1024]; Populate(arr1); var arr2 = new Quote[(1024 - 129) * 1024 - 1]; Populate(arr2); var arr3 = new Quote[1025]; Populate(arr3); var quote1 = new Quote(0.5m, 1, Guid.NewGuid().ToString(), 1, null, 1); var quote2 = new Quote(0.6m, 1, Guid.NewGuid().ToString(), 1, null, 1); var quote3 = new Quote(0.7m, 1, Guid.NewGuid().ToString(), 1, null, 1); var fullArray = new Quote[size + 3]; Array.Copy(arr1, 0, fullArray, 0, arr1.Length); Array.Copy(arr2, 0, fullArray, arr1.Length, arr2.Length); Array.Copy(arr3, 0, fullArray, arr1.Length + arr2.Length, arr3.Length); fullArray[fullArray.Length - 3] = quote1; fullArray[fullArray.Length - 2] = quote2; fullArray[fullArray.Length - 1] = quote3; fullArray = fullArray.OrderByDescending(x => x.QuotePrice).ToArray(); var heaps = new[] { CreateMaxHeap(arr1, 0), CreateMaxHeap(arr2, 1), CreateMaxHeap(arr3, 2) }; var askHeap = new BidHeap(heaps); heaps[0].InsertVal(quote1); heaps[1].InsertVal(quote2); heaps[2].InsertVal(quote3); var position = new SellPosition(fullArray.Length); var sw = Stopwatch.StartNew(); Parallel.For(0, 1, i => { var cnt = 0; do { position.LastSize = 0; askHeap.FindPriceAdjustSize(position); Assert.True(fullArray[cnt].QuotePrice.Equals(position.LastPrice)); } while (++cnt < fullArray.Length); position.LastSize = 0; askHeap.FindPriceAdjustSize(position); Assert.True(position.LastSize.Equals(0)); }); sw.Stop(); Console.Out.WriteLine($"AskHeap Extract Time:{sw.Elapsed.TotalMilliseconds}"); }
public async Task <TradeResponse> TradeAsync(SellPosition sell) { var response = new TradeResponse { TradeSummary = new List <string>(), Initial = $"{sell.Current}" }; var tasks = new List <Task <TradeInfo> >(); var keepLooping = true; var cnt = 0; var dollarVal = 0m; var tradeSize = 0m; var sw = Stopwatch.StartNew(); while (keepLooping) { sell.LastSize = 0; _bidHeap.FindPriceAdjustSize(sell); while (!sell.LastSize.Equals(0m)) { tasks.Add(GetSellTask(sell)); sell.LastSize = 0; _bidHeap.FindPriceAdjustSize(sell); } if (tasks.Count > 0) { //We can change this using Interleaved Tasks logic to gain some perf! var finished = await Task.WhenAny(tasks).ConfigureAwait(false); tasks.Remove(finished); var info = await finished.ConfigureAwait(false); response.TradeSummary.Add(info.Summary(++cnt)); sell.AddSize(info.Remains); dollarVal += info.DollarValue; tradeSize += info.TradeSize; } else { keepLooping = false; } } sw.Stop(); response.Untraded = $"{decimal.Round(sell.Current, 8)}"; response.TotalValue = $"{decimal.Round(dollarVal, 2)} $"; response.TotalTraded = $"{tradeSize}"; response.MsTime = ((int)(sw.Elapsed.TotalMilliseconds * 1000)) / 1000.0m; return(response); }