I figured it out. Alas, my plan failed miserably. I was trying to find
the fastest way to invoke 'get' methods. Anybody have a faster method
of getting data than those below? Here is my test code:
using System;
using System.Diagnostics;
using System.Reflection;
using NUnit.Framework;
namespace Asi.Tests.Xml
{
[TestFixture]
public class DynamicInvoker
{
public class Inker
{
public int Count;
public int ReadAndInc1 { get { return Count++; } }
public int ReadAndInc2 { get { return Count++; } }
public int ReadAndInc3 { get { return Count++; } }
public int ReadAndInc4 { get { return Count++; } }
public int ReadAndInc5 { get { return Count++; } }
}
static public TR RunFunc<T, TR>(MethodInfo meth, T target)
{
var func = (Func<T, TR>) Delegate.CreateDelegate(typeof (Func<T,
TR>), meth);
return func.Invoke(target);
}
public object InvokeFunc(MethodInfo meth, object obj)
{
if(!meth.ReflectedType.Equals(obj.GetType()))
throw new InvalidOperationException();
_makerSW.Start();
var genmeth = _maker.MakeGenericMethod(meth.ReflectedType,
meth.ReturnType);
_makerSW.Stop();
object ret = genmeth.Invoke(this, new[] { meth, obj });
return ret;
}
private MethodInfo _maker;
private readonly Stopwatch _makerSW = new Stopwatch();
[Test][Explicit("Too slow normally")]
public void DynamicInvokeSpeed()
{
var rand = new Random();
var sw1 = new Stopwatch();
var i1 = new Inker();
sw1.Reset(); sw1.Start();
object cnt = -1;
for (int i = 0; i < 100000; i++)
{
var prop = i1.GetType().GetProperty("ReadAndInc" + rand.Next(1,
5));
var meth = prop.GetGetMethod();
var del = (Func<Inker,
int>)Delegate.CreateDelegate(typeof(Func<Inker, int>), meth);
cnt = del.Invoke(i1);
}
Console.Out.WriteLine("hard-coded took " +
sw1.Elapsed.TotalSeconds);
var parms = new object[] { };
_maker = GetType().GetMethod("RunFunc", BindingFlags.Static |
BindingFlags.Public);
_makerSW.Reset();
sw1.Reset(); sw1.Start();
for (int i = 0; i < 100000; i++)
{
var prop = i1.GetType().GetProperty("ReadAndInc" + rand.Next(1,
5));
var meth = prop.GetGetMethod();
cnt = InvokeFunc(meth, i1);
}
Console.Out.WriteLine("Dynamic took " + sw1.Elapsed.TotalSeconds);
Console.Out.WriteLine("GenericMaker took " +
_makerSW.Elapsed.TotalSeconds);
sw1.Reset(); sw1.Start();
for (int i = 0; i < 100000; i++)
{
var prop = i1.GetType().GetProperty("ReadAndInc" + rand.Next(1,
5));
var meth = prop.GetGetMethod();
cnt = meth.Invoke(i1, parms);
}
Console.Out.WriteLine("Invoke took " + sw1.Elapsed.TotalSeconds);
sw1.Reset(); sw1.Start();
for (int i = 0; i < 100000; i++)
{
var prop = i1.GetType().GetProperty("ReadAndInc" + rand.Next(1,
5));
cnt = prop.GetValue(i1, null);
}
Console.Out.WriteLine("Reflect took " + sw1.Elapsed.TotalSeconds);
Console.Out.WriteLine("Cnt = " + cnt);
}
}
}