Skip to content

Instantly share code, notes, and snippets.

@ig-sinicyn
Last active May 11, 2016 14:41
Show Gist options
  • Save ig-sinicyn/29a2d814060a58c531039c82bdd3704b to your computer and use it in GitHub Desktop.
Save ig-sinicyn/29a2d814060a58c531039c82bdd3704b to your computer and use it in GitHub Desktop.
using System;
using System.Diagnostics;
namespace CodeDrafts
{
static class Program
{
struct A
{
public uint a1;
public uint a2;
}
struct B
{
public ulong b1;
}
//[MethodImpl(MethodImplOptions.NoInlining)]
unsafe static B FromAUnsafe(A a)
{
return *(B*)&a;
}
//[MethodImpl(MethodImplOptions.NoInlining)]
static B FromA(A a)
{
return new B { b1 = (ulong)a.a2 << 32 | a.a1 };
}
static void Main(string[] args)
{
Console.WriteLine(IntPtr.Size == 4? "x86" : "x64");
Console.WriteLine(typeof(string).Assembly.FullName);
Console.WindowWidth = 120;
const int Count = 100 * 1000 * 1000;
Measure("Original", () =>
{
var a = new A() { a1 = 1, a2 = 2 };
var b = new B();
for (int i = 0; i < Count; i++)
{
b = FromA(a);
}
return Count;
});
Measure("OptimisedNoCall", () =>
{
var a = new A() { a1 = 1, a2 = 2 };
var b = new B();
for (int i = 0; i < Count; i++)
{
b = FromAUnsafe(a);
}
return Count;
});
Measure("OptimisedWithCall", () =>
{
var a = new A() { a1 = 1, a2 = 2 };
var b = new B();
for (int i = 0; i < Count; i++)
{
b = FromAUnsafe(a);
}
SimpleCall(b);
return Count;
});
Measure("OptimisedCallBox", () =>
{
var a = new A() { a1 = 1, a2 = 2 };
var b = new B();
for (int i = 0; i < Count; i++)
{
b = FromAUnsafe(a);
}
CallBoxed(b);
return Count;
});
Measure("OptimisedCallBoxStore", () =>
{
var a = new A() { a1 = 1, a2 = 2 };
var b = new B();
for (int i = 0; i < Count; i++)
{
b = FromAUnsafe(a);
}
CallStoreBoxed(b);
return Count;
});
Measure("OptimisedCallStore", () =>
{
var a = new A() { a1 = 1, a2 = 2 };
var b = new B();
for (int i = 0; i < Count; i++)
{
b = FromAUnsafe(a);
}
CallStore(b);
return Count;
});
Console.Write("Done...");
Console.ReadKey();
}
private static void SimpleCall(B b)
{
}
private static void CallBoxed(object b)
{
}
private static object _b1;
private static void CallStoreBoxed(object b)
{
_b1 = b;
}
private static B _b2;
private static void CallStore(B b)
{
_b2 = b;
}
private static void Measure(string name, Func<long> callback)
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
var mem = GC.GetTotalMemory(true);
var gc00 = GC.CollectionCount(0);
var gc01 = GC.CollectionCount(1);
var gc02 = GC.CollectionCount(2);
var sw = Stopwatch.StartNew();
var result = callback();
sw.Stop();
var mem2 = GC.GetTotalMemory(false);
var gc10 = GC.CollectionCount(0);
var gc11 = GC.CollectionCount(1);
var gc12 = GC.CollectionCount(2);
var memDelta = (mem2 - mem) / 1024.0;
var gcDelta0 = gc10 - gc00;
var gcDelta1 = gc11 - gc01;
var gcDelta2 = gc12 - gc02;
Console.WriteLine(
"{0,22}: {1,5}ms, ips: {2,22:N} | Mem: {3,9:N2} kb, GC 0/1/2: {4}/{5}/{6} => {7,6}",
name, sw.ElapsedMilliseconds, result / sw.Elapsed.TotalSeconds, memDelta, gcDelta0, gcDelta1, gcDelta2, result);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment