Skip to content

Instantly share code, notes, and snippets.

@tmakin
Last active February 1, 2017 12:27
Show Gist options
  • Save tmakin/e47601befdd9e502485ab729dcf1f83f to your computer and use it in GitHub Desktop.
Save tmakin/e47601befdd9e502485ab729dcf1f83f to your computer and use it in GitHub Desktop.
//Source: https://codeblog.jonskeet.uk/2011/08/22/optimization-and-generics-part-1-the-new-constraint/
using System;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
#pragma warning disable 0169
public class SmallClass { int x; }
public class LargeClass { long a, b, c, d, e, f, g, h; }
public struct SmallStruct { int x; }
public struct LargeStruct { long a, b, c, d, e, f, g, h; }
#pragma warning restore 0169
public class Benchmark
{
static Action[] Tests =
{
SmallStructFromExpression,
SmallStructWithConstraint,
SmallStructWithProvider,
LargeStructFromExpression,
LargeStructWithConstraint,
LargeStructWithProvider,
SmallClassFromExpression,
SmallClassWithConstraint,
SmallClassWithProvider,
LargeClassFromExpression,
LargeClassWithConstraint,
LargeClassWithProvider,
};
private static Func<SmallStruct> smallStructConstructor = GetCtor<SmallStruct>();
private static Func<SmallClass> smallClassConstructor = GetCtor<SmallClass>();
private static Func<LargeStruct> largeStructConstructor = GetCtor<LargeStruct>();
private static Func<LargeClass> largeClassConstructor = GetCtor<LargeClass>();
private static Func<T> GetCtor<T>()
{
Type type = typeof(T);
Expression body = Expression.New(type);
return Expression.Lambda<Func<T>>(body).Compile();
}
private static void SmallStructWithConstraint()
=> MakeInstance<SmallStruct>();
private static void SmallStructWithProvider()
=> MakeInstance<SmallStruct>(() => new SmallStruct());
private static void SmallStructFromExpression()
=> MakeInstance<SmallStruct>(smallStructConstructor);
private static void LargeStructWithConstraint()
=> MakeInstance<LargeStruct>();
private static void LargeStructWithProvider()
=> MakeInstance<LargeStruct>(() => new LargeStruct());
private static void LargeStructFromExpression()
=> MakeInstance<LargeStruct>(largeStructConstructor);
private static void SmallClassWithConstraint()
=> MakeInstance<SmallClass>();
private static void SmallClassWithProvider()
=> MakeInstance<SmallClass>(() => new SmallClass());
private static void SmallClassFromExpression()
=> MakeInstance<SmallClass>(smallClassConstructor);
private static void LargeClassWithConstraint()
=> MakeInstance<LargeClass>();
private static void LargeClassWithProvider()
=> MakeInstance<LargeClass>(() => new LargeClass());
private static void LargeClassFromExpression()
=> MakeInstance<LargeClass>(largeClassConstructor);
private static void MakeInstance<T>() where T : new()
{
T t = new T();
UseValue(t);
}
private static void MakeInstance<T>(Func<T> provider) where T : new()
{
T t = provider();
UseValue(t);
}
private static void UseValue<T>(T instance)
{
// Do nothing...
}
// -------------- INFRASTRUCTURE BELOW HERE --------------
const int Iterations = 100000000;
static void Main()
{
Console.WriteLine("Environment: CLR {0} on {1}", Environment.Version, Environment.OSVersion);
// Warm up
RunTests(1, false, 0);
int maxMethodLength = Tests.Select(x => x.Method.Name.Length).Max();
// Real thing
RunTests(Iterations, true, maxMethodLength);
}
static void RunTests(int count, bool displayResults, int maxLength)
{
foreach (Action action in Tests)
{
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
action();
}
sw.Stop();
if (displayResults)
{
Console.WriteLine("{0}: {1}ms", action.Method.Name.PadRight(maxLength),
((int)sw.ElapsedMilliseconds).ToString().PadLeft(6));
}
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment