I am interested to know the technical reasons: why does reflection not perform well in .NET?
Because it involves string lookups (of type and member names) at run-time, as well as extra boxing/unboxing for value types.
Terrific article on that on MSDN: Dodge Common Performance Pitfalls to Craft Speedy Applications. Basically, it's a question of late and early binding. That is, what can be decided at compile-time and what must be decided at runtime. From that article ...
The late-bound cases are MethodBase.Invoke, DynamicMethod via Invoke, Type.InvokeMember, and late-bound delegate calls (calls on delegates via Delegate.DynamicInvoke). All of these methods come with significantly more negative performance implications than the early-bound cases. Even in the best case, they're typically an order of magnitude slower than the slowest early-bound case.
He breaks our quite a few performance tests of the various ways of making early and late bound calls. Well worth the read.
Reflection involves going to the metadata to resolve the names to tokens, it then uses this tokens for lookup and retrieving the data you want ( for example, a method token is used to get the information about the method, parameters ...etc).
This process is expensive because of 2 reasons. 1- A lot of lookup is going on. 2- Touching pages that are not usually touched ( cold pages ), which contain the metadata tables.
Accessing Metadata directly is expensive, the CLR maintain caches to make this process fast and to avoid touching the metadata tables when you access things in non-reflection way, however once you go to reflection, we bypass these caches and go directly to the source.
reflection does not perform well
That's a very loaded statement. "Perform well" is relative. Compared to static code, reflective calls do not perform quite as well. However, in nearly all cases, reflection in .NET is extremely fast. I cannot understate that enough. Reflection got a bad reputation from .NET 1.x days and perhaps other languages, but reflection in .NET 2.0+ is blisteringly quick.
In 99% of cases, the "is reflection too slow" is an irrelevant concern. I doubt you would need to bother measuring the performance impact of a reflective call vs a static one.
Reflection does perform well in .NET - for what it does.
However, reflection, since it's a runtime analysis of already compiled types, requires quite a bit of overhead. In general, doing things like string lookups of static type information, and walking the class metadata, etc, is going to take a while.
That isn't to say that it's really slow - it's just a LOT slower than fully compiled, strait method calls and lookups. It should be - but I really think of it more as compiled code is faster than dynamically looking up information, in any system.
Simply stating that "Reflection" performs slow is lumping a hell of a lot of functionality underneath a very broad blanket. Reflection in .NET comes in several classes, each with a different level of "performance". For one, use of the typeof()
operator is actually a form of reflection...it queries the CLR metadata for a type. However, typeof()
executes extremely fast (in near-free time.) Use of other type-related "reflection", such as the is operator, sizeof()
operator, etc. are also nearly free (they basically perform as if they were static code.)
Reflection used to retrieve information about a type, while slower than typeof()
, is also very, very fast considering the amount of pointer traversal and metadata probing that goes on. Metadata probing is a fairly common practice with .NET code, particularly when it comes to working with custom attributes.
The big performance concern in regards to reflection has to do with invocation. Accessing type information and reading metadata are pretty light weight. The moment you involve dynamic invocation of properties, indexers, methods, or dynamically construct new types via reflection, you take an orders-of-magnitude performance hit.
Reflection is still an in-process execution, however, so before you worry about the performance hit of a little dynamic invocation, make sure that there aren't any significantly larger performance bottlenecks, such as inter-process execution, network calls (i.e. database, web service, etc.) When it comes to performance, start with the biggest performance hit, and work your way down from there. Reflection, including dynamic invocation, is usually one of the last things you should worry about from a performance standpoint.
Addendum:
A bit of an after thought, but if you require a high degree of dynamic invocation of late-bound type members, you should look into lightweight code generation. Using the System.Reflection.Emit namespace, you can use utilities such as DynamicMethod to generate lightweight code at runtime that can perform early-bound calls. Caching this generated code reduces the initial cost of generating it, allowing you to gain the benefit of late-bound calls with early-bound performance.
Reflection performs well, it just does a lot more than static code.
Say you have this code snippet:
typeof(SomeClass).GetMethod("SomeStaticMethod").
Invoke(null, new object[] { 1, 2, 3 });
This is the same as this:
SomeClass.SomeStaticMethod(1, 2, 3);
But it should be obvious that the first one has a lot more work to do. It has to get type information, traverse it to see if there's a SomeStaticMethod method, check what kind of method it is, invoke the method on an instance, or not if it's static and pass the object array is parameters, boxing/unboxing the integers in this case as well.
And this is probably a very broad summary, there's no doubt even more going on. Yet despite this, reflection is still very fast and used in a lot of areas, from databinding on WinForms to model binding in ASP.NET MVC (every request you make to this site, built on MVC, involves a whole bunch of reflection and yet, the site is very fast and MVC is regarded as a very fast framework).