Skip to content

@ermau /gist:3855949

Embed URL


Subversion checkout URL

You can clone with
Download ZIP
DynamicMethod creation: 0.0053597000ms
LINQ expressions creation: 0.1050939000ms
DynamicMethod invocation: 0.0000474000ms
Expression invocation: 0.0000450000ms
MethodInfo invocation: 0.0002190000ms
Calls to reach even with MethodInfo:
DynamicMethod: 24.6899543379
Expression: 480.086301369866
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using Cadenza;
namespace Getter
static class Program
static void Main(string[] args)
PropertyInfo prop = typeof (Foo).GetProperty ("Name");
//Console.WriteLine (CreateDynamicMethodDelegate (prop) (new Foo { Name = "bar " }));
//Console.WriteLine (CreateGetPropertyDelegate (prop) (new Foo { Name = "bar " }));
Action<PropertyInfo> createDynamic = p => CreateDynamicMethodDelegate (p);
Action<PropertyInfo> createExpr = p => CreateGetPropertyDelegate (p);
double createDynamicTime = createDynamic.Timings (prop, 1000).Average (t => t.TotalMilliseconds);
double createExpressionTime = createExpr.Timings (prop, 1000).Average (t => t.TotalMilliseconds);
Console.WriteLine ("DynamicMethod creation: {0:N10}ms", createDynamicTime);
Console.WriteLine ("LINQ expressions creation: {0:N10}ms", createExpressionTime);
Foo foo = new Foo { Name = "bar" };
Func<object, object> getNameDynamic = CreateDynamicMethodDelegate (prop);
Action<Func<object, object>, Foo> testDynamic = (d, o) => d (o);
double getDyanmicTime = testDynamic.Timings (getNameDynamic, foo, 1000).Average (t => t.TotalMilliseconds);
Func<object, object> getNameExpression = CreateDynamicMethodDelegate (prop);
Action<Func<object, object>, Foo> testExpression = (d, o) => d (o);
double getExpressionTime = testExpression.Timings (getNameExpression, foo, 1000).Average (t => t.TotalMilliseconds);
Action<MethodInfo, Foo> testMethod = (m, f) => m.Invoke (f, null);
double getMethodTime = testMethod.Timings (prop.GetMethod, foo, 1000).Average (t => t.TotalMilliseconds);
Console.WriteLine ("DynamicMethod invocation: {0:N10}ms", getDyanmicTime);
Console.WriteLine ("Expression invocation: {0:N10}ms", getExpressionTime);
Console.WriteLine ("MethodInfo invocation: {0:N10}ms", getMethodTime);
Console.WriteLine ("Calls to reach even with MethodInfo:");
Console.WriteLine ("DynamicMethod: " + ((createDynamicTime + getDyanmicTime) / getMethodTime));
Console.WriteLine ("Expression: " + ((createExpressionTime + getExpressionTime) / getMethodTime));
private static Func<object, object> CreateDynamicMethodDelegate (PropertyInfo prop)
DynamicMethod method = new DynamicMethod ("name", typeof(object), new[] { typeof (object) });
ILGenerator gen = method.GetILGenerator();
gen.Emit (OpCodes.Ldarg_0);
gen.Emit (OpCodes.Castclass, prop.DeclaringType);
gen.Emit (OpCodes.Callvirt, prop.GetMethod);
gen.Emit (OpCodes.Ret);
return (Func<object,object>)method.CreateDelegate (typeof (Func<object, object>));
private static Func<object, object> CreateGetPropertyDelegate (PropertyInfo prop)
var instance = Expression.Parameter(typeof(object), "instance");
var instCast = prop.GetGetMethod(true).IsStatic ? null : Expression.Convert(instance, prop.ReflectedType);
var propAcc = Expression.Property(instCast, prop);
var castProp = Expression.Convert(propAcc, typeof(object));
var lambda = Expression.Lambda<Func<object, object>> (castProp, instance);
return lambda.Compile();
public class Foo
public string Name
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.