From 81eb45f4f868386b8fea80a99a62a4c2dc2566c5 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kukrash Date: Sat, 12 Jul 2025 04:27:06 +0200 Subject: [PATCH 1/4] Disable Nagle algorithm for reduced latency --- .../Network/Abstractions/TcpServer.cs | 1 + SerializersBenchmark/Network/Rabbit.cs | 27 ++++++++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/SerializersBenchmark/Network/Abstractions/TcpServer.cs b/SerializersBenchmark/Network/Abstractions/TcpServer.cs index 361f9cf..a1bf68c 100644 --- a/SerializersBenchmark/Network/Abstractions/TcpServer.cs +++ b/SerializersBenchmark/Network/Abstractions/TcpServer.cs @@ -21,6 +21,7 @@ public void Start() while (true) { _connectedClient = await _tcpListener.AcceptTcpClientAsync(); + _connectedClient.Client.NoDelay = true;//disable Nagle's algorithm for low latency await OnClientConnected(_connectedClient); } } diff --git a/SerializersBenchmark/Network/Rabbit.cs b/SerializersBenchmark/Network/Rabbit.cs index f32048f..c50106a 100644 --- a/SerializersBenchmark/Network/Rabbit.cs +++ b/SerializersBenchmark/Network/Rabbit.cs @@ -4,28 +4,37 @@ namespace SerializersBenchmark.Network; -public sealed class Rabbit(ISerializerTestAsync serializer, int port, bool useBufferedStream = false) : IRabbit, ITcpClient +public sealed class Rabbit : IRabbit, ITcpClient { - private readonly TcpClient _tcpClient = new(); + private readonly TcpClient _tcpClient; private NetworkStream _networkStream; + private readonly ISerializerTestAsync _serializer; + private readonly int _port; + private readonly bool _useBufferedStream; + public Rabbit(ISerializerTestAsync serializer, int port, bool useBufferedStream = false) { + _serializer = serializer; + _port = port; + _useBufferedStream = useBufferedStream; + _tcpClient = new TcpClient(); + _tcpClient.Client.NoDelay = true; //disable Nagle's algorithm for low latency + } - public async Task ConnectAsync() - { - await _tcpClient.ConnectAsync("127.0.0.1", port); + public async Task ConnectAsync() { + await _tcpClient.ConnectAsync("127.0.0.1", _port); _networkStream = _tcpClient.GetStream(); } public async Task SendAsync(object value, int repeatCount) { Stream stream = _networkStream; - if (useBufferedStream) + if (_useBufferedStream) { stream = new BufferedStream(stream); } for (var i = 0; i < repeatCount; i++) { - await serializer.SerializeAsync(value, stream).ConfigureAwait(false); + await _serializer.SerializeAsync(value, stream).ConfigureAwait(false); } await _networkStream.FlushAsync().ConfigureAwait(false); @@ -34,11 +43,11 @@ public async Task SendAsync(object value, int repeatCount) public async Task ReceiveAsync(int expectedSize) { Stream stream = new LimitedStreamReader(_networkStream, expectedSize); - if (useBufferedStream) + if (_useBufferedStream) { stream = new BufferedStream(stream); } - return await serializer.DeserializeAsync(stream).ConfigureAwait(false); + return await _serializer.DeserializeAsync(stream).ConfigureAwait(false); } public void Dispose() From d0101ad146027a758795bd9172527dbffa6d0949 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kukrash Date: Sat, 12 Jul 2025 04:30:04 +0200 Subject: [PATCH 2/4] Flush proper stream --- SerializersBenchmark/Network/Rabbit.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SerializersBenchmark/Network/Rabbit.cs b/SerializersBenchmark/Network/Rabbit.cs index c50106a..94aee84 100644 --- a/SerializersBenchmark/Network/Rabbit.cs +++ b/SerializersBenchmark/Network/Rabbit.cs @@ -37,7 +37,7 @@ public async Task SendAsync(object value, int repeatCount) await _serializer.SerializeAsync(value, stream).ConfigureAwait(false); } - await _networkStream.FlushAsync().ConfigureAwait(false); + await stream.FlushAsync().ConfigureAwait(false); } public async Task ReceiveAsync(int expectedSize) From f002c028c7cfd2c86e215109b480d86a2fd7c64b Mon Sep 17 00:00:00 2001 From: Aliaksandr Kukrash Date: Sat, 12 Jul 2025 04:35:03 +0200 Subject: [PATCH 3/4] Move localhost IP address into constant --- SerializersBenchmark/Network/Abstractions/TcpServer.cs | 3 ++- SerializersBenchmark/Network/Rabbit.cs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/SerializersBenchmark/Network/Abstractions/TcpServer.cs b/SerializersBenchmark/Network/Abstractions/TcpServer.cs index a1bf68c..7f420d0 100644 --- a/SerializersBenchmark/Network/Abstractions/TcpServer.cs +++ b/SerializersBenchmark/Network/Abstractions/TcpServer.cs @@ -5,7 +5,8 @@ namespace SerializersBenchmark.Network.Abstractions; public abstract class TcpServer(int port) : IServer { - private readonly TcpListener _tcpListener = new(IPAddress.Parse("127.0.0.1"), port); + public const string LOCALHOST = "127.0.0.1"; + private readonly TcpListener _tcpListener = new(IPAddress.Parse(LOCALHOST), port); private TcpClient _connectedClient; protected bool TeardownStarted; diff --git a/SerializersBenchmark/Network/Rabbit.cs b/SerializersBenchmark/Network/Rabbit.cs index 94aee84..89adb79 100644 --- a/SerializersBenchmark/Network/Rabbit.cs +++ b/SerializersBenchmark/Network/Rabbit.cs @@ -16,11 +16,11 @@ public Rabbit(ISerializerTestAsync serializer, int port, bool useBufferedStream _port = port; _useBufferedStream = useBufferedStream; _tcpClient = new TcpClient(); - _tcpClient.Client.NoDelay = true; //disable Nagle's algorithm for low latency + _tcpClient.Client.NoDelay = true; // disable Nagle's algorithm for low latency } public async Task ConnectAsync() { - await _tcpClient.ConnectAsync("127.0.0.1", _port); + await _tcpClient.ConnectAsync(TcpServer.LOCALHOST, _port).ConfigureAwait(false); _networkStream = _tcpClient.GetStream(); } From 830f68f5db6aad7bfd6d2ef1f6e2812298dd6a19 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kukrash Date: Sat, 12 Jul 2025 04:38:03 +0200 Subject: [PATCH 4/4] Use loopback shortcut --- SerializersBenchmark/Network/Abstractions/TcpServer.cs | 5 ++--- SerializersBenchmark/Network/Rabbit.cs | 7 ++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/SerializersBenchmark/Network/Abstractions/TcpServer.cs b/SerializersBenchmark/Network/Abstractions/TcpServer.cs index 7f420d0..ba8596f 100644 --- a/SerializersBenchmark/Network/Abstractions/TcpServer.cs +++ b/SerializersBenchmark/Network/Abstractions/TcpServer.cs @@ -5,8 +5,7 @@ namespace SerializersBenchmark.Network.Abstractions; public abstract class TcpServer(int port) : IServer { - public const string LOCALHOST = "127.0.0.1"; - private readonly TcpListener _tcpListener = new(IPAddress.Parse(LOCALHOST), port); + private readonly TcpListener _tcpListener = new(IPAddress.Loopback, port); private TcpClient _connectedClient; protected bool TeardownStarted; @@ -22,7 +21,7 @@ public void Start() while (true) { _connectedClient = await _tcpListener.AcceptTcpClientAsync(); - _connectedClient.Client.NoDelay = true;//disable Nagle's algorithm for low latency + _connectedClient.Client.NoDelay = true; //disable Nagle's algorithm for low latency await OnClientConnected(_connectedClient); } } diff --git a/SerializersBenchmark/Network/Rabbit.cs b/SerializersBenchmark/Network/Rabbit.cs index 89adb79..219ce55 100644 --- a/SerializersBenchmark/Network/Rabbit.cs +++ b/SerializersBenchmark/Network/Rabbit.cs @@ -1,4 +1,5 @@ -using System.Net.Sockets; +using System.Net; +using System.Net.Sockets; using SerializersBenchmark.Base; using SerializersBenchmark.Network.Abstractions; @@ -16,11 +17,11 @@ public Rabbit(ISerializerTestAsync serializer, int port, bool useBufferedStream _port = port; _useBufferedStream = useBufferedStream; _tcpClient = new TcpClient(); - _tcpClient.Client.NoDelay = true; // disable Nagle's algorithm for low latency + _tcpClient.Client.NoDelay = true; //disable Nagle's algorithm for low latency } public async Task ConnectAsync() { - await _tcpClient.ConnectAsync(TcpServer.LOCALHOST, _port).ConfigureAwait(false); + await _tcpClient.ConnectAsync(IPAddress.Loopback, _port).ConfigureAwait(false); _networkStream = _tcpClient.GetStream(); }