Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reflection.Emit better than GetValue & SetValue :S

I've been told to use Reflection.Emit instead of PropertyInfo.GetValue / SetValue because it is faster this way. But I don't really know what stuff from Reflection.Emit and how to use it to substitute GetValue and SetValue. Can anybody help me with this ?

like image 521
Omu Avatar asked Nov 26 '09 15:11

Omu


5 Answers

Just an alternative answer; if you want the performance, but a similar API - consider HyperDescriptor; this uses Reflection.Emit underneath (so you don't have to), but exposes itself on the PropertyDescriptor API, so you can just use:

PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj);
props["Name"].SetValue(obj, "Fred");
DateTime dob = (DateTime)props["DateOfBirth"].GetValue(obj);

One line of code to enable it, and it handles all the caching etc.

like image 184
Marc Gravell Avatar answered Nov 12 '22 09:11

Marc Gravell


If you're fetching/setting the same property many times, then using something to build a typesafe method will indeed be faster than reflection. However, I would suggest using Delegate.CreateDelegate instead of Reflection.Emit. It's easier to get right, and it's still blazingly fast.

I've used this in my Protocol Buffers implementation and it made a huge difference vs PropertyInfo.GetValue/SetValue. As others have said though, only do this after proving that the simplest way is too slow.

I have a blog post with more details if you decide to go down the CreateDelegate route.

like image 41
Jon Skeet Avatar answered Nov 12 '22 09:11

Jon Skeet


Use PropertyInfo.GetValue/SetValue

If you have performance problems cache the PropertyInfo object (don't repeatedly call GetProperty)

If - and only if - the use of reflection is the performance bottleneck of your app (as seen in a profiler) use Delegate.CreateDelegate

If - and really really only if - you are absolutely sure that reading/writing the values is still the worst bottleneck it's time to start learning about the fun world of generating IL in runtime.

I really doubt it's worth it, each of those levels increase the complexity of the code more then they improve performance - do them only if you have to.

And if runtime access to properties is your performance bottleneck it's probably better going for compile time access (it's hard time to be both generic and super high performance at the same time).

like image 28
Nir Avatar answered Nov 12 '22 09:11

Nir


The purpose of Reflection.Emit is completely different from that of PropertyInfo.Get/SetValue. Via Reflection.Emit, you can directly emit IL code, for example into dynamically compiled assemblies, and execute this code. Of course, this code could access your properties.

I seriously doubt that this will be much quicker then using PropertyInfo in the end, and it's not made for this purpose either. You could use Reflection.Emit as the code generator for a small compiler, for example.

like image 1
Maximilian Mayerl Avatar answered Nov 12 '22 08:11

Maximilian Mayerl


Using Reflection.Emit seems a little too "clever", as well as a premature optimization. If you profile your application, and you find that the GetValue/SetValue Reflection is the bottleneck, then you could consider optimizing, but probably not even then...

like image 1
John Buchanan Avatar answered Nov 12 '22 07:11

John Buchanan