Skip to content

Instantly share code, notes, and snippets.

@neon-sunset
Created July 15, 2023 14:48
Show Gist options
  • Save neon-sunset/fed48339292c0cc1f153bf30ffb1ebca to your computer and use it in GitHub Desktop.
Save neon-sunset/fed48339292c0cc1f153bf30ffb1ebca to your computer and use it in GitHub Desktop.
using System.Runtime.CompilerServices;
var repro = new Example(new object(), 1234, 5678);
PrintAsMinOpts(repro);
PrintAs(repro);
PrintBitcast(repro);
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
static void PrintAsMinOpts(Example example)
{
Console.WriteLine("--- MinOpts");
Console.WriteLine($"Offset: {example.OffsetAsMinOpts}");
Console.WriteLine($"Length: {example.LengthAsMinOpts}");
}
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
static void PrintAs(Example example)
{
Console.WriteLine("--- As");
Console.WriteLine($"Offset: {example.OffsetAs}");
Console.WriteLine($"Length: {example.LengthAs}");
}
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
static void PrintBitcast(Example example)
{
Console.WriteLine("--- Bitcast");
Console.WriteLine($"Offset: {example.OffsetBitcast}");
Console.WriteLine($"Length: {example.LengthBitcast}");
}
readonly struct Example
{
public readonly object? Value;
public readonly ulong Inner;
struct ExampleInner
{
public int Offset;
public int Length;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Example(object? value, int offset, int length)
{
var inner = new ExampleInner
{
Offset = offset,
Length = length
};
Value = value;
Inner = Unsafe.As<ExampleInner, ulong>(ref inner);
}
public int OffsetAsMinOpts
{
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
get
{
var inner = Inner;
return Unsafe.As<ulong, ExampleInner>(ref inner).Offset;
}
}
public int OffsetAs
{
[MethodImpl(MethodImplOptions.AggressiveOptimization | MethodImplOptions.NoInlining)]
get
{
var inner = Inner;
return Unsafe.As<ulong, ExampleInner>(ref inner).Offset;
}
}
public int OffsetBitcast => Unsafe.BitCast<ulong, ExampleInner>(Inner).Offset;
public int LengthAsMinOpts
{
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
get
{
var inner = Inner;
return Unsafe.As<ulong, ExampleInner>(ref inner).Length;
}
}
public int LengthAs
{
[MethodImpl(MethodImplOptions.AggressiveOptimization | MethodImplOptions.NoInlining)]
get
{
var inner = Inner;
return Unsafe.As<ulong, ExampleInner>(ref inner).Length;
}
}
public int LengthBitcast => Unsafe.BitCast<ulong, ExampleInner>(Inner).Length;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment