Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
MethodInfo.Invoke is slow... open instance delegate to the rescue
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<A, int, int> 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<Action<A, int, int>>(body, p1, p2, p3).Compile();
}
private static Action<A, int, int> CreateOpenDelegate(MethodInfo mi)
{
var openDelegate = Delegate.CreateDelegate(
typeof(Action<A, int, int>),
null,
mi,
true);
return (Action<A, int, int>)openDelegate;
}
}
public class A
{
public void Foo(int a, int b)
{
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment