From e07f7c75c95275affb07d159cbc2df5dd7d7cfe2 Mon Sep 17 00:00:00 2001 From: lidgren Date: Fri, 20 Jan 2012 09:52:19 +0000 Subject: [PATCH] NetOutgoingMessage.Write(float) optimized to avoid memory allocation --- Lidgren.Network/NetOutgoingMessage.Write.cs | 27 +++++++++++++++------ UnitTests/ReadWriteTests.cs | 4 +-- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/Lidgren.Network/NetOutgoingMessage.Write.cs b/Lidgren.Network/NetOutgoingMessage.Write.cs index e94d551..e2f88fc 100644 --- a/Lidgren.Network/NetOutgoingMessage.Write.cs +++ b/Lidgren.Network/NetOutgoingMessage.Write.cs @@ -21,9 +21,21 @@ using System.Collections.Generic; using System.Net; using System.Reflection; using System.Text; +using System.Runtime.InteropServices; namespace Lidgren.Network { + [StructLayout(LayoutKind.Explicit)] + public struct SingleUIntUnion + { + [FieldOffset(0)] + public float SingleValue; + + [FieldOffset(0)] + [CLSCompliant(false)] + public uint UIntValue; + } + public sealed partial class NetOutgoingMessage { private const int c_overAllocateAmount = 4; @@ -386,17 +398,16 @@ namespace Lidgren.Network /// public void Write(float source) { - byte[] val = BitConverter.GetBytes(source); + // Use union to avoid BitConverter.GetBytes() which allocates memory on the heap + SingleUIntUnion su; + su.UIntValue = 0; // must initialize every member of the union to avoid warning + su.SingleValue = source; + #if BIGENDIAN // swap byte order - byte tmp = val[3]; - val[3] = val[0]; - val[0] = tmp; - tmp = val[2]; - val[2] = val[1]; - val[1] = tmp; + su.UIntValue = NetUtility.SwapByteOrder(su.UIntValue); #endif - Write(val); + Write(su.UIntValue); } #endif diff --git a/UnitTests/ReadWriteTests.cs b/UnitTests/ReadWriteTests.cs index cec9961..1e3a705 100644 --- a/UnitTests/ReadWriteTests.cs +++ b/UnitTests/ReadWriteTests.cs @@ -49,7 +49,7 @@ namespace UnitTests int bcnt = 0; - msg.Write(45.0f); + msg.Write(567845.0f); msg.WriteVariableInt32(2115998022); msg.Write(46.0); bcnt += msg.WriteVariableInt32(-47); @@ -94,7 +94,7 @@ namespace UnitTests bdr.Append(inc.ReadVariableUInt32()); bdr.Append(inc.ReadVariableInt64()); - if (bdr.ToString().Equals("False-342duke of earl4344True45211599802246-4747000048-49")) + if (bdr.ToString().Equals("False-342duke of earl4344True567845211599802246-4747000048-49")) Console.WriteLine("Read/write tests OK"); else throw new NetException("Read/write tests FAILED!");