Created
January 24, 2023 20:22
-
-
Save arturaz/85f88dc97a7888914e442aa8be4a0fa5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Diagnostics; | |
using System.Runtime.InteropServices; | |
using System.Text; | |
using UnityEngine; | |
using Debug = UnityEngine.Debug; | |
public unsafe class TestInVsPointer : MonoBehaviour | |
{ | |
// 8 * 8 = 64 bytes | |
readonly struct Large3 { readonly ulong p1, p2, p3, p4, p5, p6, p7, p8; } | |
// 8 * 64 = 512 bytes | |
readonly struct Large2 { readonly Large3 p1, p2, p3, p4, p5, p6, p7, p8; } | |
// 8 * 512 = 4kb | |
readonly struct Large1 { readonly Large2 p1, p2, p3, p4, p5, p6, p7, p8; } | |
// 8 * 4kb = 32kb | |
struct Large { public Large1 p1; } | |
readonly struct LargeRO { readonly Large1 p1; } | |
static Large large; | |
static LargeRO largeRO; | |
delegate void ActionPtr<A>(A* ptr) where A : unmanaged; | |
// Start is called before the first frame update | |
void Start() { | |
fixed (Large* largePtr = &large) { | |
fixed (LargeRO* largeROPtr = &largeRO) { | |
benchmark($"large (size={Marshal.SizeOf(large)})", 0, _ => take(large)); | |
benchmark($"large in (size={Marshal.SizeOf(large)})", 0, _ => takeIn(large)); | |
benchmark($"large ptr (size={Marshal.SizeOf(large)})", largePtr, takePtr); | |
benchmark($"largeRO (size={Marshal.SizeOf(largeRO)})", 0, _ => take(largeRO)); | |
benchmark($"largeRO in (size={Marshal.SizeOf(largeRO)})", 0, _ => takeIn(largeRO)); | |
benchmark($"largeRO ptr (size={Marshal.SizeOf(largeRO)})", largeROPtr, takePtr); | |
Debug.Log(sb.ToString()); | |
} | |
} | |
} | |
void take<A>(A a) { | |
} | |
void takeIn<A>(in A a) { | |
} | |
void takePtr<A>(A* a) where A : unmanaged { | |
} | |
static readonly StringBuilder sb = new StringBuilder(); | |
static readonly Stopwatch sw = new Stopwatch(); | |
const int TIMES = 5_000_000; | |
static void benchmark<Data>(string name, Data data, Action<Data> action) { | |
sw.Restart(); | |
for (var idx = 0; idx < TIMES; idx++) { | |
action(data); | |
} | |
sw.Stop(); | |
var perRun = sw.Elapsed.TotalMilliseconds / TIMES; | |
sb.Append($"{name} took total={sw.Elapsed}, per run={perRun:F}ms\n"); | |
} | |
static void benchmark<Data>(string name, Data* data, ActionPtr<Data> action) where Data : unmanaged { | |
sw.Restart(); | |
for (var idx = 0; idx < TIMES; idx++) { | |
action(data); | |
} | |
sw.Stop(); | |
var perRun = sw.Elapsed.TotalMilliseconds / TIMES; | |
sb.Append($"{name} took total={sw.Elapsed}, per run={perRun:F}ms\n"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment