diff --git a/DtronixMessageQueue.Tests.Performance/Program.cs b/DtronixMessageQueue.Tests.Performance/Program.cs index 8d402cf..1282ba0 100644 --- a/DtronixMessageQueue.Tests.Performance/Program.cs +++ b/DtronixMessageQueue.Tests.Performance/Program.cs @@ -64,18 +64,8 @@ static void Main(string[] args){ StartServer(total_messages, total_clients); }else if (mode == "single-process") { - Task.Run(() => { - StartServer(total_messages, total_clients); - }); WriteSysInfo(); - Console.WriteLine("| Messages | Msg Bytes | Milliseconds | MPS | MBps |"); - Console.WriteLine("|------------|-----------|--------------|------------|----------|"); - - for (int i = 0; i < total_clients; i++) { - Task.Run(() => { - StartClient(total_loops, total_messages, total_frames, frame_size); - }); - } + InProcessTest(); } @@ -239,5 +229,126 @@ private static byte[] RandomBytes(int len) { return val; } + + + static void InProcessTest() { + + var small_message = new MqMessage { + new MqFrame(RandomBytes(50), MqFrameType.More), + new MqFrame(RandomBytes(50), MqFrameType.More), + new MqFrame(RandomBytes(50), MqFrameType.More), + new MqFrame(RandomBytes(50), MqFrameType.Last) + }; + + MqInProcessPerformanceTests(1000000, 5, small_message); + + var medimum_message = new MqMessage { + new MqFrame(RandomBytes(500), MqFrameType.More), + new MqFrame(RandomBytes(500), MqFrameType.More), + new MqFrame(RandomBytes(500), MqFrameType.More), + new MqFrame(RandomBytes(500), MqFrameType.Last) + }; + + MqInProcessPerformanceTests(100000, 5, medimum_message); + + var large_message = new MqMessage { + new MqFrame(RandomBytes(MqFrame.MaxFrameSize), MqFrameType.More), + new MqFrame(RandomBytes(MqFrame.MaxFrameSize), MqFrameType.More), + new MqFrame(RandomBytes(MqFrame.MaxFrameSize), MqFrameType.More), + new MqFrame(RandomBytes(MqFrame.MaxFrameSize), MqFrameType.Last) + }; + + MqInProcessPerformanceTests(10000, 5, large_message); + + Console.WriteLine("Performance complete"); + + Console.ReadLine(); + } + + private static void MqInProcessPerformanceTests(int runs, int loops, MqMessage message) { + var server = new MqServer(new SocketConfig { + Ip = "127.0.0.1", + Port = 2828 + }); + server.Start(); + + double[] total_values = { 0, 0, 0 }; + + var count = 0; + var sw = new Stopwatch(); + var wait = new AutoResetEvent(false); + var complete_test = new AutoResetEvent(false); + + var client = new MqClient(new SocketConfig() { + Ip = "127.0.0.1", + Port = 2828 + }); + + Console.WriteLine("| Build | Messages | Msg Bytes | Milliseconds | MPS | MBps |"); + Console.WriteLine("|---------|------------|-----------|--------------|------------|----------|"); + + + var message_size = message.Size; + + server.IncomingMessage += (sender, args2) => { + MqMessage message_out; + count += args2.Messages.Count; + + + if (count == runs) { + sw.Stop(); + var mode = "Release"; + +#if DEBUG + mode = "Debug"; +#endif + + var messages_per_second = (int)((double)runs / sw.ElapsedMilliseconds * 1000); + var msg_size_no_header = message_size - 12; + var mbps = runs * (double)(msg_size_no_header) / sw.ElapsedMilliseconds / 1000; + Console.WriteLine("| {0,7} | {1,10:N0} | {2,9:N0} | {3,12:N0} | {4,10:N0} | {5,8:N2} |", mode, runs, msg_size_no_header, sw.ElapsedMilliseconds, messages_per_second, mbps); + total_values[0] += sw.ElapsedMilliseconds; + total_values[1] += messages_per_second; + total_values[2] += mbps; + + + wait.Set(); + } + + }; + + + + var send = new Action(() => { + count = 0; + sw.Restart(); + for (var i = 0; i < runs; i++) { + client.Send(message); + } + //MqServer sv = server; + wait.WaitOne(); + wait.Reset(); + + }); + + client.Connected += (sender, args) => { + for (var i = 0; i < loops; i++) { + send(); + } + + Console.WriteLine("| | | AVERAGES | {0,12:N0} | {1,10:N0} | {2,8:N2} |", total_values[0] / loops, total_values[1] / loops, total_values[2] / loops); + Console.WriteLine(); + + server.Stop(); + client.Close(); + complete_test.Set(); + }; + + client.Connect(); + + complete_test.WaitOne(); + } + } + } diff --git a/DtronixMessageQueue.Tests.Performance/Results/i7-6500U-16GB.md b/DtronixMessageQueue.Tests.Performance/Results/i7-6500U-16GB.md index 961bfef..2a2aaff 100644 --- a/DtronixMessageQueue.Tests.Performance/Results/i7-6500U-16GB.md +++ b/DtronixMessageQueue.Tests.Performance/Results/i7-6500U-16GB.md @@ -2,27 +2,27 @@ Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz with 16 GB of RAM installed. | Build | Messages | Msg Bytes | Milliseconds | MPS | MBps | |---------|------------|-----------|--------------|------------|----------| -| Release | 1,000,000 | 200 | 1,674 | 597,371 | 119.47 | -| Release | 1,000,000 | 200 | 1,593 | 627,746 | 125.55 | -| Release | 1,000,000 | 200 | 1,589 | 629,326 | 125.87 | -| Release | 1,000,000 | 200 | 1,599 | 625,390 | 125.08 | -| Release | 1,000,000 | 200 | 1,629 | 613,873 | 122.77 | -| | | AVERAGES | 1,617 | 618,741 | 123.75 | +| Release | 1,000,000 | 200 | 2,199 | 454,752 | 90.95 | +| Release | 1,000,000 | 200 | 2,187 | 457,247 | 91.45 | +| Release | 1,000,000 | 200 | 2,149 | 465,332 | 93.07 | +| Release | 1,000,000 | 200 | 2,209 | 452,693 | 90.54 | +| Release | 1,000,000 | 200 | 2,143 | 466,635 | 93.33 | +| | | AVERAGES | 2,177 | 459,332 | 91.87 | | Build | Messages | Msg Bytes | Milliseconds | MPS | MBps | |---------|------------|-----------|--------------|------------|----------| -| Release | 100,000 | 2,000 | 927 | 107,874 | 215.75 | -| Release | 100,000 | 2,000 | 879 | 113,765 | 227.53 | -| Release | 100,000 | 2,000 | 894 | 111,856 | 223.71 | -| Release | 100,000 | 2,000 | 888 | 112,612 | 225.23 | -| Release | 100,000 | 2,000 | 902 | 110,864 | 221.73 | -| | | AVERAGES | 898 | 111,394 | 222.79 | +| Release | 100,000 | 2,000 | 1,239 | 80,710 | 161.42 | +| Release | 100,000 | 2,000 | 1,243 | 80,450 | 160.90 | +| Release | 100,000 | 2,000 | 1,231 | 81,234 | 162.47 | +| Release | 100,000 | 2,000 | 1,239 | 80,710 | 161.42 | +| Release | 100,000 | 2,000 | 1,233 | 81,103 | 162.21 | +| | | AVERAGES | 1,237 | 80,841 | 161.68 | | Build | Messages | Msg Bytes | Milliseconds | MPS | MBps | |---------|------------|-----------|--------------|------------|----------| -| Release | 10,000 | 60,000 | 2,725 | 3,669 | 220.18 | -| Release | 10,000 | 60,000 | 2,733 | 3,658 | 219.54 | -| Release | 10,000 | 60,000 | 2,712 | 3,687 | 221.24 | -| Release | 10,000 | 60,000 | 2,728 | 3,665 | 219.94 | -| Release | 10,000 | 60,000 | 2,755 | 3,629 | 217.79 | -| | | AVERAGES | 2,731 | 3,662 | 219.74 | \ No newline at end of file +| Release | 10,000 | 16,372 | 1,091 | 9,165 | 150.06 | +| Release | 10,000 | 16,372 | 1,090 | 9,174 | 150.20 | +| Release | 10,000 | 16,372 | 1,094 | 9,140 | 149.65 | +| Release | 10,000 | 16,372 | 1,085 | 9,216 | 150.89 | +| Release | 10,000 | 16,372 | 1,141 | 8,764 | 143.49 | +| | | AVERAGES | 1,100 | 9,092 | 148.86 | \ No newline at end of file diff --git a/DtronixMessageQueue/Socket/SocketServer.cs b/DtronixMessageQueue/Socket/SocketServer.cs index 391291e..00600d9 100644 --- a/DtronixMessageQueue/Socket/SocketServer.cs +++ b/DtronixMessageQueue/Socket/SocketServer.cs @@ -66,9 +66,14 @@ private void StartAccept(SocketAsyncEventArgs e) { } connection_limit.WaitOne(); - if (MainSocket.AcceptAsync(e) == false) { - AcceptCompleted(e); + try { + if (MainSocket.AcceptAsync(e) == false) { + AcceptCompleted(e); + } + } catch (ObjectDisposedException) { + // ignored } + } // This method is the callback method associated with Socket.AcceptAsync @@ -111,6 +116,9 @@ public void Stop() { foreach (var session in sessions) { session.CloseConnection(SocketCloseReason.ServerClosing); } + + //MainSocket.Shutdown(SocketShutdown.Both); + MainSocket.Close(); } } diff --git a/README.md b/README.md index 179d19d..60f344f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ DtronixMessageQueue [![Build Status](https://travis-ci.org/Dtronix/DtronixMessageQueue.svg?branch=master)](https://travis-ci.org/Dtronix/DtronixMessageQueue) ============ -DtronixMessageQueue is a small .net TCP/UDP message queueing system based upon [kerryjiang's SuperSocket](https://github.com/kerryjiang/SuperSocket) +DtronixMessageQueue is a small .net TCP/UDP message queueing system using the microsoft [SocketAsyncEventArgs](https://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs(v=vs.110).aspx) interface The purpose of this project is to provide a simple transport protocol for multiple systems, mostly being the DtronixRpc system. @@ -9,8 +9,5 @@ The purpose of this project is to provide a simple transport protocol for multip [Desktop Intel i5-3470 8GB](DtronixMessageQueue.Tests.Performance/Results/i5-3470-8GB.md) -Messages sizes exclude the 3 bytes header for the packet and the 3 byte header for each frame. -Each message is 4 frames long. - ### License -Released under MIT license +Released under [MIT license](LICENSE)