I'm having performance problems with using reflection.
So I decided to create delegates for the properties of my objects and so far got this:
TestClass cwp = new TestClass();
var propertyInt = typeof(TestClass).GetProperties().Single(obj => obj.Name == "AnyValue");
var access = BuildGetAccessor(propertyInt.GetGetMethod());
var result = access(cwp);
static Func<object, object> BuildGetAccessor(MethodInfo method)
{
var obj = Expression.Parameter(typeof(object), "o");
Expression<Func<object, object>> expr =
Expression.Lambda<Func<object, object>>(
Expression.Convert(
Expression.Call(
Expression.Convert(obj, method.DeclaringType),
method),
typeof(object)),
obj);
return expr.Compile();
}
The results were highly satisfactory, about 30-40 times faster than using the conventional method (PropertyInfo.GetValue (obj, null);
)
The problem is: How can I make a SetValue
of a property, which works the same way? Unfortunately did not get a way.
I am doing so because I can not use methods with <T>
because of the structure of my application.
Use dynamic types. They use reflection under the hood, but they're a lot faster.
Otherwise...
There are tons of free faster reflection libraries out there with permissive licenses. I would link you, but there are too many, and I'm not sure which would suit you. Just search codeplex etc. When you find something you like, try it out.
But yeah, maybe before that, think if reflection really is the answer. Often there are other solutions.
Edit: As Requested...
http://geekswithblogs.net/SunnyCoder/archive/2009/06/26/c-4.0-dynamics-vs.-reflection.aspx
http://theburningmonk.com/2010/09/performance-test-dynamic-method-invocation-in-csharp-4/
http://www.mssoftwareconsulting.com/msswc/blog/post/C-40-and-dynamic-performance.aspx
It's common knowledge as far as I can tell.
I think you'd be better off with
CreateDelegate
construct if performance is the key. Since you know the signature of the method beforehand, which here is justGetGetMethod
andGetSetMethod
of thePropertyInfo
, you can create a delegate to execute the very method with the same signature directly. Expressions would be better suited if you need to build some logic (for which you did not have a method handle) to delegates. I did some benchmarking on different routes to this problem:I would, in your case, write:
So now you call:
Isn't that simpler?? Had written a generic class here to handle the exact thing.
This should work for you:
Usage:
With
TestClass
:Prints out: