Skip to main content
3 of 3
added 326 characters in body
Kittoes0124
  • 1.9k
  • 2
  • 18
  • 24

Expanding on my comment; below you'll find a very simple program that compares the method I suggested with your original example. The results on my machine show that the MemoryMarshal class is about 85x faster. You might want to experiment a bit and try running a similar test with a larger struct; maybe your method is faster for the specific problem that you're trying to solve.

Comparison Code:

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System;
using System.Runtime.InteropServices;

public readonly struct SomeStruct
{
    private readonly ulong m_x;
    private readonly ulong m_y;
    private readonly ulong m_z;

    public ulong X => m_x;
    public ulong Y => m_y;
    public ulong Z => m_z;

    public SomeStruct(ulong x, ulong y, ulong z) {
        m_x = x;
        m_y = y;
        m_z = z;
    }
}

public class Race
{
    private readonly byte[] m_data = new byte[] {
        0, 0, 0, 0, 0, 0, 0, 0,
        1, 0, 0, 0, 0, 0, 0, 0,
        1, 255, 0, 0, 0, 0, 0, 0,
    };

    [Benchmark(Baseline = true)]
    public SomeStruct A() => MemoryMarshal.Read<SomeStruct>(m_data);
    [Benchmark]
    public SomeStruct B() => Program.ReadUsingMarshalUnsafe<SomeStruct>(m_data, 0, m_data.Length);
}

class Program
{
    static void Main(string[] args) {
        var summary = BenchmarkRunner.Run<Race>();

        Console.ReadKey();
    }

    public static T ReadUsingMarshalUnsafe<T>(byte[] data, int startIndex, int length) {
        byte[] fixedData = new byte[length];
        unsafe {
            fixed (byte* pSource = data, pTarget = fixedData) {
                int index = 0;
                for (int i = startIndex; i < data.Length; i++) {
                    pTarget[index] = pSource[i];
                    index++;
                }
            }

            fixed (byte* p = &fixedData[0]) {
                return (T)Marshal.PtrToStructure(new IntPtr(p), typeof(T));
            }
        }
    }
}

**BenchmarkDotNet Results:**

Benchmark results.

Kittoes0124
  • 1.9k
  • 2
  • 18
  • 24