Skip to content

Commit

Permalink
Max speed (0.0ns) and safer ConstructRid
Browse files Browse the repository at this point in the history
  • Loading branch information
pkdawson committed Sep 9, 2024
1 parent 14eb84c commit 14e05b6
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 25 deletions.
9 changes: 5 additions & 4 deletions addons/imgui-godot/ImGuiGodot/Internal/Util.cs
Original file line number Diff line number Diff line change
@@ -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<ulong> uspan = new(in id);
ReadOnlySpan<byte> bytes = MemoryMarshal.Cast<ulong, byte>(uspan);
return MemoryMarshal.Read<Rid>(bytes);
}
}
32 changes: 11 additions & 21 deletions doc/test/csbench/BenchRid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Reflection.Emit;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

namespace csbench;

Expand All @@ -11,7 +10,6 @@ public class BenchRid
{
private readonly Func<ulong, Rid> _constructRid;
private readonly ulong _id = 12345;
private readonly nint _buf;

public BenchRid()
{
Expand All @@ -25,11 +23,9 @@ public BenchRid()
il.Emit(OpCodes.Newobj, cinfo);
il.Emit(OpCodes.Ret);
_constructRid = dm.CreateDelegate<Func<ulong, Rid>>();

_buf = Marshal.AllocHGlobal(Marshal.SizeOf<Rid>());
}

[Benchmark(Baseline = true)]
[Benchmark]
public Rid ConstructRid_Emitted()
{
return _constructRid(_id);
Expand All @@ -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<Rid>(_buf);
return rv;
Span<byte> bytes = stackalloc byte[sizeof(ulong)];
MemoryMarshal.TryWrite(bytes, in _id);
return MemoryMarshal.Read<Rid>(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<ulong> uspan = new(in _id);
ReadOnlySpan<byte> bytes = MemoryMarshal.Cast<ulong, byte>(uspan);
return MemoryMarshal.Read<Rid>(bytes);
}

[Benchmark]
public unsafe Rid ConstructRid_Unsafe_Direct()
[Benchmark(Baseline = true)]
public unsafe Rid ConstructRid_Unsafe_DirectCopy()
{
Rid rv;
fixed (ulong* p = &_id)
Expand Down

0 comments on commit 14e05b6

Please sign in to comment.