Last active
April 11, 2021 20:54
-
-
Save buybackoff/e2f92cfb35f7e7ea32e2ea9afb4298ee to your computer and use it in GitHub Desktop.
ByRefCtor
This file contains 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.CompilerServices; | |
namespace ByRefCtor | |
{ | |
public readonly struct Test | |
{ | |
private static ref TestMut AsMutable(ref Test d) => ref Unsafe.As<Test, TestMut>(ref d); | |
public readonly long _value; | |
public readonly long _value1; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public Test(double value) | |
{ | |
TestMut.Init(value, out this); | |
} | |
private struct TestMut | |
{ | |
private long _value; | |
private long _value1; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static void Init(double input, out Test mut) | |
{ | |
Unsafe.SkipInit(out mut); | |
Unsafe.As<Test, TestMut>(ref mut)._value = (long) input; | |
Unsafe.As<Test, TestMut>(ref mut)._value1 = ((long) input) >> 1; | |
} | |
} | |
} | |
public readonly struct Test1 | |
{ | |
private static ref TestMut1 AsMutable(ref Test1 d) => ref Unsafe.As<Test1, TestMut1>(ref d); | |
public readonly long _value; | |
public readonly long _value1; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public Test1(double value) | |
{ | |
this = default; | |
TestMut1.Init(value, ref AsMutable(ref this)); | |
} | |
private struct TestMut1 | |
{ | |
private long _value; | |
private long _value1; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static void Init(double input, ref TestMut1 test) | |
{ | |
test._value = (long) input; | |
test._value1 = ((long) input) >> 1; | |
} | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var count = 1000_000_000; | |
for (int r = 0; r < 10; r++) | |
{ | |
RunTest(count); | |
RunTest1(count); | |
} | |
} | |
[MethodImpl(MethodImplOptions.NoInlining)] | |
private static void RunTest(int count) | |
{ | |
long sum; | |
Stopwatch sw; | |
sum = 0; | |
sw = Stopwatch.StartNew(); | |
for (int i = 0; i < count; i++) | |
{ | |
sum += new Test(i)._value; | |
} | |
sw.Stop(); | |
Console.WriteLine($"Test: {sw.ElapsedMilliseconds}"); | |
} | |
[MethodImpl(MethodImplOptions.NoInlining)] | |
private static void RunTest1(int count) | |
{ | |
long sum; | |
Stopwatch sw; | |
sum = 0; | |
sw = Stopwatch.StartNew(); | |
for (int i = 0; i < count; i++) | |
{ | |
sum += new Test1(i)._value; | |
} | |
sw.Stop(); | |
Console.WriteLine($"Test1: {sw.ElapsedMilliseconds}"); | |
} | |
} | |
} |
This file contains 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.Runtime.CompilerServices; | |
namespace ByRefCtor | |
{ | |
public readonly struct Test | |
{ | |
private static ref TestMut AsMutable(ref Test d) => ref Unsafe.As<Test, TestMut>(ref d); | |
private readonly long _value; | |
public Test(double value) | |
{ | |
// `ref this` works here: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Decimal.cs#L166-L176 | |
TestMut.Init(value, out AsMutable(ref this)); | |
} | |
private struct TestMut | |
{ | |
private long _value; | |
public static void Init(double input, out TestMut mut) | |
{ | |
mut = default; | |
mut._value = (long) input; | |
} | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
Console.WriteLine("Hello World!"); | |
} | |
} | |
} |
This file contains 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.Runtime.CompilerServices; | |
namespace ByRefCtor | |
{ | |
public readonly struct Test | |
{ | |
private static ref TestMut AsMutable(ref Test d) => ref Unsafe.As<Test, TestMut>(ref d); | |
private readonly long _value; | |
public Test(double value) | |
{ | |
TestMut.Init(value, out this); | |
} | |
private struct TestMut | |
{ | |
private long _value; | |
public static void Init(double input, out Test mut) | |
{ | |
Unsafe.SkipInit(out mut); | |
Unsafe.As<Test, TestMut>(ref mut)._value = (long) input; | |
} | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
Console.WriteLine("Hello World!"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment