0

I find many answers to my question and they all work. My question is are they all equal in speed and memory. How can I tell what is faster and uses less memory. I don't normally use the Marshal and GCHandle classes. So I am totally green.

public static object RawDeserializer(byte[] rawData, int position, Type anyType)
        {
            int rawsize = Marshal.SizeOf(anyType);
            if (rawsize > rawData.Length)
                return null;
            IntPtr buffer = Marshal.AllocHGlobal(rawsize);
            Marshal.Copy(rawData, position, buffer, rawsize);
            object retobj = Marshal.PtrToStructure(buffer, anyType);
            Marshal.FreeHGlobal(buffer);
            return retobj;
        }

public static T RawDeserializer<T>(byte[] rawData, int position = 0)
        {
            int rawsize = Marshal.SizeOf(typeof(T));
            if (rawsize > rawData.Length)
            {
                throw new DataMisalignedException("byte array is not the correct size for the requested type");
            }
            IntPtr buffer = Marshal.AllocHGlobal(rawsize);
            Marshal.Copy(rawData, position, buffer, rawsize);
            T retobj = (T)Marshal.PtrToStructure(buffer, typeof(T));
            Marshal.FreeHGlobal(buffer);
            return retobj;
        }


public static T RawDeserializer<T>(byte[] bytes) where T : struct
        {
            T stuff;
            GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
            try
            {
                stuff = Marshal.PtrToStructure<T>(handle.AddrOfPinnedObject());
            }
            finally
            {
                handle.Free();
            }
            return stuff;
        }

I am getting the desired results form all 3 implementations.

1 Answer 1

2

First and second are almost identical: difference is that you do not unbox (cast to T:struct) the result in the first example, I'd assume that you'll unbox it later though.

Third option does not copy memory to the unmanaged heap, it just pins it in manageed heap, so I'd assume it will allocate less memory and will be faster. I don't pretend to be a golden source of truth though, so just go and make performance testing of these options :) BenchmarkDotNet is a great framework for performance testing and may help you a lot.

Also third option could be more concise:

public static unsafe T RawDeserializer<T>(byte[] bytes) where T : struct
{
    fixed (byte* p = bytes)
         return Marshal.PtrToStructure<T>((IntPtr)p);
}

You need to change project settings to allow unsafe code though: enter image description here

To do not be totally green, I'd strongly recommend to read a book CLR via C#, Chapter 21 'The Managed Heap and Garbage Collection'.

Sign up to request clarification or add additional context in comments.

1 Comment

I'm doing homework you assign me now. I did see other examples of using "fixed" keyword. I understood it less than my other examples so I shied away from it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.