using System; using System.Diagnostics; using System.Linq.Expressions; using System.Reflection; namespace ConsoleApplication3 { class Program { static void Main(string[] args) { var mi = typeof(A).GetMethod("Foo"); Console.WriteLine("Regular method"); Time(() => new A().Foo(1, 2)); Console.WriteLine(); Console.WriteLine("Invoke"); Time(() => mi.Invoke(new A(), new object[] { 1, 2 })); Console.WriteLine(); Console.WriteLine("Cached Delegate"); var cache = Compile(mi); Time(() => cache.Invoke(new A(), 1, 2)); Console.WriteLine(); Console.WriteLine("Open Delegate"); var od = CreateOpenDelegate(mi); Time(() => od.Invoke(new A(), 1, 2)); } private static void Time(Action a) { var sw = Stopwatch.StartNew(); for (int i = 0; i < 10000000; i++) { a(); } sw.Stop(); Console.WriteLine(sw.Elapsed); } private static Action Compile(MethodInfo mi) { // Params var p1 = Expression.Parameter(typeof(A)); var p2 = Expression.Parameter(typeof(int)); var p3 = Expression.Parameter(typeof(int)); // Body var body = Expression.Call(p1, mi, p2, p3); // compile return Expression.Lambda>(body, p1, p2, p3).Compile(); } private static Action CreateOpenDelegate(MethodInfo mi) { var openDelegate = Delegate.CreateDelegate( typeof(Action), null, mi, true); return (Action)openDelegate; } } public class A { public void Foo(int a, int b) { } } }