Click here to Skip to main content
15,886,799 members
Please Sign up or sign in to vote.
4.75/5 (4 votes)
See more:
Hey,

I'm writing nowadays a custom entity framework, in which my entities define their own data members marked by custom attributes.

My entities inherit an abstract base class which knows to gather information using reflection about the properties during run-time (instead of having to deal with annoying abstract functions that would yield them for every entity type...), the properties can of course be cached statically, so that overhead is avoided.

Still, The most expensive price I have to pay is when setting and getting values from an object. I would like to minimize that. I've already tried several approaches, (PropertyInfo, Reflection.Emit, Fasterflect...), have seen some benchmark results, etc. However, as this is a rather low-level in my framework, and it doesn't expose any interfaces, I would prefer it would be as fast as possible even if the code will not be as pretty...

Thanks :)
Posted
Comments
Sergey Alexandrovich Kryukov 22-Jan-13 11:43am    
I must say, this is an interesting question touching a very important problem. I voted 5 for the question (which happens very, very rarely, by the way).
I really hope my answer could be useful; it is based on real experience, really observing dramatic performance boost.

—SA

Ultimately, Reflection.Emit is the best way to go. If you found that it is unsuitable, you probably missed something. I don't know what exactly you are trying to achieve, so just some hints:

You don't have to create a whole separate assembly with Emit. You may choose to create separate methods. You can use System.Reflection.Emit.DynamicMethod, http://msdn.microsoft.com/en-us/library/system.reflection.emit.dynamicmethod.aspx[^].

You can combine Emit with caching the results. Consider this highly simplified scenario:

Why would you need to pass some types through Reflection at all? Only because you need to create some processing of these types and their instances, agnostic to those types, in advance. You take some types, process them with Reflection, and create some reflected artifacts in memory. If could be a set of DynamicMethod instances, or, better, delegate instances based on such methods, and some other information you dig out with Reflection: names, base types, etc.

Create a class to store all the results of such Reflection and Emit, call if, say, ReflectionCache.

All you need is to do it all once, not repeatedly. So, you need to create some dictionary indexed with some key. You can use System.Type as the key. Use, for example, System.Collections.Generic.Dictionary<System.Type,ReflectionCache>.

Each time you need to work with some type, you first looks for reflection cache in the dictionary. It if is found, use it: invoke delegate instanced obtained from DynamicType instances your emitted before, and so on. If the type is not found (remember, the type is the key), do extra Reflection and Emit. This way, you reach the goal: doing Reflection and Emit only once.

—SA
 
Share this answer
 
v2
Comments
fjdiewornncalwe 22-Jan-13 13:42pm    
+5. Excellent.
Sergey Alexandrovich Kryukov 22-Jan-13 13:57pm    
Thank you very much, Marcus.
—SA
ShacharK 22-Jan-13 17:09pm    
It is indeed an excellent answer. Your insights were very helpful, I thank you very much for that.
Sergey Alexandrovich Kryukov 22-Jan-13 17:13pm    
My pleasure. And thank you, too — for this interesting question.
Good luck, call again.
—SA
There are some useful suggestions in the answer to this post ...http://stackoverflow.com/questions/771524/how-slow-is-reflection[^]
 
Share this answer
 
Comments
PIEBALDconsult 22-Jan-13 11:12am    
As long as you're doing all the Reflection up front, caching the xxxInfo for each, and maintain arrays for passing the parameters, I have no other ideas.
Sergey Alexandrovich Kryukov 22-Jan-13 11:38am    
Exactly! Such caching is the key: after all, the goal is doing Reflection and Emit only once per type. The mechanism just should be agnostic to some set of types.

I tried to explain it and provided some advice in my answer, please see.
—SA
Sergey Alexandrovich Kryukov 22-Jan-13 11:41am    
I did not vote for this answer, because the discussion does not give definitive advice, and some of the answers are not very qualified. Please look at my answer: it is based on my positive experience.
—SA
Simply caching PropertyInfo (or FieldInfo etc) objects in a hashtable of string -> property was fast enough for quite a reflection-heavy problem for me.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 22-Jan-13 11:39am    
Very basically, the idea is right, but the gain in performance is actually very low. I tried it and found it does not pay off. In contrast, some deeper approach come out great. It's harder to achieve though, but pay off is just great.

Please see my answer.
—SA
BobJanova 22-Jan-13 11:47am    
The gain was significant for me. What I was doing was populating a data table from a data object through reflection (because the data object could be of different types), and the time to look up the properties (through GetFields) was a lot more than the time to read all the values and populate the grid. Caching the FieldInfo objects made the UI refresh go from painful to not noticable.

Using Reflection.Emit is another step down the same road: a larger performance gain but more obfuscation and complication in the mechanism.
Sergey Alexandrovich Kryukov 22-Jan-13 11:51am    
I agree with your. The gain is a relative thing, also, it depends...
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900