Original Post
I've just been thinking about this today... What is the fastest way to convert structures to an array of bytes in C#?
Here are two ways I've come up with using generics:
[source lang="csharp"]
public unsafe static byte[] GetBytes(this T value)
where T : struct
{
int size = Marshal.SizeOf(typeof(T));
var buffer = new byte[size];
var pSrc = (byte*)Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(value, (IntPtr)pSrc, true);
fixed (byte* bp = buffer)
for (int i = 0; i < size; ++i)
*(bp + i) = *(pSrc++);
return buffer;
}
public static byte[] GetBytes2(this T value)
where T : struct
{
int size = Marshal.SizeOf(typeof(T));
var buffer = new byte[size];
GCHandle pin = GCHandle.Alloc(value, GCHandleType.Pinned);
try
{
Marshal.Copy(pin.AddrOfPinnedObject(), buffer, 0, buffer.Length);
return buffer;
}
finally { pin.Free(); }
}
[/source]
I really HATE how C# won't allow you to take the address of type T where T: struct... It will let you take the address of a struct, but not a struct used in the context of generics... I think that's stupid, and I wish they'd fix it! AFAIK it's faster to manipulate raw bytes by using pointers and turning off bounds checking than iterating through a managed array the usual way (by indexing). Can anyone confirm/deny this?
So does anyone know the fastest way to do this, and what pros/cons there are to each method? I just ran a test of both of these methods using System.Diagnostics.Stopwatch, and it appears that both are executing in only 1-3 ticks...!? If that is the case it apparently makes little difference, but GetBytes2() is coming in, on average, at 2 ticks whereas GetBytes takes an average of 3 ticks. So I suppose GetBytes2 appears to be about 33.33% faster. I suspect it might make a more considerable difference when much larger data is being worked with or lots of small structures must be serialized in rapid succession (e.g., each frame of a video game).
Anyone have yet an even faster way of doing things? And what about memory efficiency? Which of these ways is more efficient and less wasteful?
Here are two ways I've come up with using generics:
[source lang="csharp"]
public unsafe static byte[] GetBytes
where T : struct
{
int size = Marshal.SizeOf(typeof(T));
var buffer = new byte[size];
var pSrc = (byte*)Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(value, (IntPtr)pSrc, true);
fixed (byte* bp = buffer)
for (int i = 0; i < size; ++i)
*(bp + i) = *(pSrc++);
return buffer;
}
public static byte[] GetBytes2
where T : struct
{
int size = Marshal.SizeOf(typeof(T));
var buffer = new byte[size];
GCHandle pin = GCHandle.Alloc(value, GCHandleType.Pinned);
try
{
Marshal.Copy(pin.AddrOfPinnedObject(), buffer, 0, buffer.Length);
return buffer;
}
finally { pin.Free(); }
}
[/source]
I really HATE how C# won't allow you to take the address of type T where T: struct... It will let you take the address of a struct, but not a struct used in the context of generics... I think that's stupid, and I wish they'd fix it! AFAIK it's faster to manipulate raw bytes by using pointers and turning off bounds checking than iterating through a managed array the usual way (by indexing). Can anyone confirm/deny this?
So does anyone know the fastest way to do this, and what pros/cons there are to each method? I just ran a test of both of these methods using System.Diagnostics.Stopwatch, and it appears that both are executing in only 1-3 ticks...!? If that is the case it apparently makes little difference, but GetBytes2() is coming in, on average, at 2 ticks whereas GetBytes takes an average of 3 ticks. So I suppose GetBytes2 appears to be about 33.33% faster. I suspect it might make a more considerable difference when much larger data is being worked with or lots of small structures must be serialized in rapid succession (e.g., each frame of a video game).
Anyone have yet an even faster way of doing things? And what about memory efficiency? Which of these ways is more efficient and less wasteful?