diff --git a/addons/imgui-godot/ImGuiGodot/Internal/Util.cs b/addons/imgui-godot/ImGuiGodot/Internal/Util.cs index 87931ab..2575e32 100644 --- a/addons/imgui-godot/ImGuiGodot/Internal/Util.cs +++ b/addons/imgui-godot/ImGuiGodot/Internal/Util.cs @@ -1,14 +1,15 @@ using Godot; using System; +using System.Runtime.InteropServices; namespace ImGuiGodot.Internal; internal static class Util { - public static unsafe Rid ConstructRid(ulong id) + public static Rid ConstructRid(ulong id) { - Rid rv; - Buffer.MemoryCopy(&id, &rv, sizeof(Rid), sizeof(ulong)); - return rv; + ReadOnlySpan uspan = new(in id); + ReadOnlySpan bytes = MemoryMarshal.Cast(uspan); + return MemoryMarshal.Read(bytes); } } diff --git a/doc/test/csbench/BenchRid.cs b/doc/test/csbench/BenchRid.cs index d2d4f15..a04ccb7 100644 --- a/doc/test/csbench/BenchRid.cs +++ b/doc/test/csbench/BenchRid.cs @@ -2,7 +2,6 @@ using System.Reflection.Emit; using System.Reflection; using System.Runtime.InteropServices; -using System.Runtime.CompilerServices; namespace csbench; @@ -11,7 +10,6 @@ public class BenchRid { private readonly Func _constructRid; private readonly ulong _id = 12345; - private readonly nint _buf; public BenchRid() { @@ -25,11 +23,9 @@ public BenchRid() il.Emit(OpCodes.Newobj, cinfo); il.Emit(OpCodes.Ret); _constructRid = dm.CreateDelegate>(); - - _buf = Marshal.AllocHGlobal(Marshal.SizeOf()); } - [Benchmark(Baseline = true)] + [Benchmark] public Rid ConstructRid_Emitted() { return _constructRid(_id); @@ -47,29 +43,23 @@ public Rid ConstructRid_Marshal() } [Benchmark] - public Rid ConstructRid_Marshal_PreAlloc() + public Rid ConstructRid_MemoryMarshal_WriteRead() { - // not thread-safe - byte[] bytes = BitConverter.GetBytes(_id); - Marshal.Copy(bytes, 0, _buf, bytes.Length); - Rid rv = Marshal.PtrToStructure(_buf); - return rv; + Span bytes = stackalloc byte[sizeof(ulong)]; + MemoryMarshal.TryWrite(bytes, in _id); + return MemoryMarshal.Read(bytes); } [Benchmark] - public unsafe Rid ConstructRid_Unsafe() + public Rid ConstructRid_MemoryMarshal_SpanCast() { - Rid rv; - byte[] bytes = BitConverter.GetBytes(_id); - fixed (byte* pbytes = bytes) - { - Buffer.MemoryCopy(pbytes, &rv, sizeof(Rid), bytes.Length); - } - return rv; + ReadOnlySpan uspan = new(in _id); + ReadOnlySpan bytes = MemoryMarshal.Cast(uspan); + return MemoryMarshal.Read(bytes); } - [Benchmark] - public unsafe Rid ConstructRid_Unsafe_Direct() + [Benchmark(Baseline = true)] + public unsafe Rid ConstructRid_Unsafe_DirectCopy() { Rid rv; fixed (ulong* p = &_id)