From d14d3e0d2d2b172d9fe8fb1fa8ce6f2f5248844a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Leone?= Date: Sat, 25 Jun 2016 20:47:29 +0200 Subject: [PATCH 1/3] Avoid array duplication of an array that is not accesible. Avoid extra array allocations with reads that require a byte array. (corrected with the comment of @Inverness) --- Lidgren.Network/NetBuffer.Read.cs | 21 ++++++++++++++++----- Lidgren.Network/NetServer.cs | 6 ++++-- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Lidgren.Network/NetBuffer.Read.cs b/Lidgren.Network/NetBuffer.Read.cs index a49b385..d083240 100644 --- a/Lidgren.Network/NetBuffer.Read.cs +++ b/Lidgren.Network/NetBuffer.Read.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Text; using System.Reflection; using System.Net; +using System.Threading; #if !__NOIPENDPOINT__ using NetEndPoint = System.Net.IPEndPoint; @@ -17,6 +18,8 @@ namespace Lidgren.Network { private const string c_readOverflowError = "Trying to read past the buffer size - likely caused by mismatching Write/Reads, different size or order."; + private static byte[] s_buffer; + /// /// Reads a boolean value (stored as a single bit) written using Write(bool) /// @@ -352,8 +355,11 @@ namespace Lidgren.Network return retval; } - byte[] bytes = ReadBytes(4); - return BitConverter.ToSingle(bytes, 0); + byte[] bytes = Interlocked.Exchange(ref s_buffer, null) ?? new byte[8]; + ReadBytes(bytes, 0, 4); + float res = BitConverter.ToSingle(bytes, 0); + s_buffer = bytes; + return res; } /// @@ -374,8 +380,10 @@ namespace Lidgren.Network return true; } - byte[] bytes = ReadBytes(4); + byte[] bytes = Interlocked.Exchange(ref s_buffer, null) ?? new byte[8]; + ReadBytes(bytes, 0, 4); result = BitConverter.ToSingle(bytes, 0); + s_buffer = bytes; return true; } @@ -394,8 +402,11 @@ namespace Lidgren.Network return retval; } - byte[] bytes = ReadBytes(8); - return BitConverter.ToDouble(bytes, 0); + byte[] bytes = Interlocked.Exchange(ref s_buffer, null) ?? new byte[8]; + ReadBytes(bytes, 0, 8); + double res = BitConverter.ToDouble(bytes, 0); + s_buffer = bytes; + return res; } // diff --git a/Lidgren.Network/NetServer.cs b/Lidgren.Network/NetServer.cs index e6ebf62..99a198f 100644 --- a/Lidgren.Network/NetServer.cs +++ b/Lidgren.Network/NetServer.cs @@ -24,7 +24,8 @@ namespace Lidgren.Network /// How to deliver the message public void SendToAll(NetOutgoingMessage msg, NetDeliveryMethod method) { - var all = this.Connections; + // Modifying m_connections will modify the list of the connections of the NetPeer. Do only reads here + var all = m_connections; if (all.Count <= 0) { if (msg.m_isSent == false) Recycle(msg); @@ -43,7 +44,8 @@ namespace Lidgren.Network /// Which sequence channel to use for the message public void SendToAll(NetOutgoingMessage msg, NetConnection except, NetDeliveryMethod method, int sequenceChannel) { - var all = this.Connections; + // Modifying m_connections will modify the list of the connections of the NetPeer. Do only reads here + var all = m_connections; if (all.Count <= 0) { if (msg.m_isSent == false) Recycle(msg); From 37d03863bb008ee6136f751e62d1af75a805f46f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Leone?= Date: Sat, 25 Jun 2016 21:28:04 +0200 Subject: [PATCH 2/3] Added a const variable to set the default size of the buffer array Using the buffer with readstring --- Lidgren.Network/NetBuffer.Read.cs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Lidgren.Network/NetBuffer.Read.cs b/Lidgren.Network/NetBuffer.Read.cs index d083240..e499a0e 100644 --- a/Lidgren.Network/NetBuffer.Read.cs +++ b/Lidgren.Network/NetBuffer.Read.cs @@ -17,7 +17,7 @@ namespace Lidgren.Network public partial class NetBuffer { private const string c_readOverflowError = "Trying to read past the buffer size - likely caused by mismatching Write/Reads, different size or order."; - + private const int c_bufferSize = 64; // Min 8 to hold anything but strings. Increase it if readed strings usally don't fit inside the buffer private static byte[] s_buffer; /// @@ -355,7 +355,7 @@ namespace Lidgren.Network return retval; } - byte[] bytes = Interlocked.Exchange(ref s_buffer, null) ?? new byte[8]; + byte[] bytes = Interlocked.Exchange(ref s_buffer, null) ?? new byte[c_bufferSize]; ReadBytes(bytes, 0, 4); float res = BitConverter.ToSingle(bytes, 0); s_buffer = bytes; @@ -380,7 +380,7 @@ namespace Lidgren.Network return true; } - byte[] bytes = Interlocked.Exchange(ref s_buffer, null) ?? new byte[8]; + byte[] bytes = Interlocked.Exchange(ref s_buffer, null) ?? new byte[c_bufferSize]; ReadBytes(bytes, 0, 4); result = BitConverter.ToSingle(bytes, 0); s_buffer = bytes; @@ -402,7 +402,7 @@ namespace Lidgren.Network return retval; } - byte[] bytes = Interlocked.Exchange(ref s_buffer, null) ?? new byte[8]; + byte[] bytes = Interlocked.Exchange(ref s_buffer, null) ?? new byte[c_bufferSize]; ReadBytes(bytes, 0, 8); double res = BitConverter.ToDouble(bytes, 0); s_buffer = bytes; @@ -604,8 +604,16 @@ namespace Lidgren.Network return retval; } - byte[] bytes = ReadBytes(byteLen); - return System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length); + if (byteLen <= c_bufferSize) { + byte[] buffer = Interlocked.Exchange(ref s_buffer, null) ?? new byte[c_bufferSize]; + ReadBytes(buffer, 0, byteLen); + string retval = Encoding.UTF8.GetString(buffer, 0, byteLen); + s_buffer = buffer; + return retval; + } else { + byte[] bytes = ReadBytes(byteLen); + return Encoding.UTF8.GetString(bytes, 0, bytes.Length); + } } /// From cc673f336435e2d4426144ba1dc6967eeb283cc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Leone?= Date: Fri, 26 Aug 2016 17:46:50 +0200 Subject: [PATCH 3/3] Support for AOT --- Lidgren.Network/NetBuffer.Read.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Lidgren.Network/NetBuffer.Read.cs b/Lidgren.Network/NetBuffer.Read.cs index e499a0e..a093490 100644 --- a/Lidgren.Network/NetBuffer.Read.cs +++ b/Lidgren.Network/NetBuffer.Read.cs @@ -18,7 +18,7 @@ namespace Lidgren.Network { private const string c_readOverflowError = "Trying to read past the buffer size - likely caused by mismatching Write/Reads, different size or order."; private const int c_bufferSize = 64; // Min 8 to hold anything but strings. Increase it if readed strings usally don't fit inside the buffer - private static byte[] s_buffer; + private static object s_buffer; /// /// Reads a boolean value (stored as a single bit) written using Write(bool) @@ -355,7 +355,7 @@ namespace Lidgren.Network return retval; } - byte[] bytes = Interlocked.Exchange(ref s_buffer, null) ?? new byte[c_bufferSize]; + byte[] bytes = (byte[]) Interlocked.Exchange(ref s_buffer, null) ?? new byte[c_bufferSize]; ReadBytes(bytes, 0, 4); float res = BitConverter.ToSingle(bytes, 0); s_buffer = bytes; @@ -380,7 +380,7 @@ namespace Lidgren.Network return true; } - byte[] bytes = Interlocked.Exchange(ref s_buffer, null) ?? new byte[c_bufferSize]; + byte[] bytes = (byte[]) Interlocked.Exchange(ref s_buffer, null) ?? new byte[c_bufferSize]; ReadBytes(bytes, 0, 4); result = BitConverter.ToSingle(bytes, 0); s_buffer = bytes; @@ -402,7 +402,7 @@ namespace Lidgren.Network return retval; } - byte[] bytes = Interlocked.Exchange(ref s_buffer, null) ?? new byte[c_bufferSize]; + byte[] bytes = (byte[]) Interlocked.Exchange(ref s_buffer, null) ?? new byte[c_bufferSize]; ReadBytes(bytes, 0, 8); double res = BitConverter.ToDouble(bytes, 0); s_buffer = bytes; @@ -605,7 +605,7 @@ namespace Lidgren.Network } if (byteLen <= c_bufferSize) { - byte[] buffer = Interlocked.Exchange(ref s_buffer, null) ?? new byte[c_bufferSize]; + byte[] buffer = (byte[]) Interlocked.Exchange(ref s_buffer, null) ?? new byte[c_bufferSize]; ReadBytes(buffer, 0, byteLen); string retval = Encoding.UTF8.GetString(buffer, 0, byteLen); s_buffer = buffer;