public
Last active

  • Download Gist
gistfile1.cs
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
/*
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();
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();
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
{
get;
set;
}
}
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.