The binary and source code for Fasterflect 1.0 (beta) can be found in the above links. You can also check out the Fasterflect CodePlex page for latest development code.

Background

If you think the built-in Reflection API in the .NET framework is too verbose for many circumstances and has poor performance, you are not alone. I think that too. And yet, being able to write reflective code is an inevitable (technical) requirement in most of the applications I develop. This is why I have built Fasterflect (read either "Faster-flect" or "Fast-reflect") as an alternative API to the .NET Reflection functionality.

The goal of this library is to make Reflection calls as straightforward as possible while offering better performance than normal Reflection calls. In this article, I'll describe the approach chosen to build Fasterflect, its APIs, and measure its performance via some benchmarks.

Implementation

Fasterflect is built based on .NET 2.0's Dynamic Methods. For those who are not familiar with Dynamic Methods, it is basically a feature which allows methods to be built at runtime using the Common Intermediate Language (CIL). After being built, dynamic methods can be casted into delegates and invoked just like normal CLR delegates.

Let's discuss a bit of the background to see how such a feature can help with the development of Fasterflect. Let's say we want to invoke a method on an object whose type we cannot (or do not want to) compile with at compile-time. We can do that using the built-in .NET Reflection API, something like this:

This works. But the performance of such Reflection calls is very poor, especially when we start executing the methods many times - a common scenario in most applications using Reflection. Not only that, the API is not very fun to play with although the above is probably one of the least verbose pieces of code based on .NET Reflection (i.e., we have not put visibility and method overloading etc. into the picture).

The latter issue is easy to address, we can just simply provide some wrapper classes offering a simpler and more fluent interface to reflection methods. The Fasterflect API simplifies things by abstracting away the concepts of MethodInfo, PropertyInfo etc., which most applications don't need to deal with, and make assumptions about the most frequently used scenarios (e.g., when we want to set the value of a field reflectively, we usually do not care to know whether that field is private or not). Following this approach will make the API very simple and lightweight. The downside is that it cannot be used as a complete replacement for the built-in .NET Reflection API in all applications out there. For example, if you only need to query the metadata for types and methods for other purposes than performing invocation, Fasterflect doesn't help. But as most applications only need to perform reflective invocations, at least in my experience, I think it's worth the while to optimize the API for such scenarios.

The former issue can be addressed by generating code at runtime. Get back to our example, the idea is that by the time someTypeName and methodToBeInvoked are already initialized with values from a config file at runtime (let's say the type name is Person and the method name is GetName), we already have enough information to construct a non-reflective piece of code like below. (Assume GenericInvocator is an interface with just one method, object GenericInvoke(object), that we already coded.)

After generating the code at runtime, we can compile it on the fly using either the csc.exe compiler or a CodeDomProvider. Assume we compile the code into an assembly, we can load and perform the invocation like below:

Notice that we only need to generate the code once, and then can reuse it for all subsequent invocations, which will be very fast because it's nothing but the direct call to person.GetName().

That is the idea. However, generating and compiling high-level code (or building a CodeDOM tree) is not the only option. Another option is generating CIL directly and skipping all the compilation overhead. We can do that either by using classes in the Reflection Emit namespace to build a .NET assembly, module, and type at runtime, or by using Dynamic Methods. Among all these options, I think Dynamic Methods is the most suitable solution. I'm not going to provide a comprehensive comparison among these options in this article, but instead highlight three key benefits of Dynamic Methods over its alternatives:

Dynamic Methods can be declared to skip visibility. If a member is declared as private, the body of a dynamic method can still access it directly instead of via Reflection. This is not the case with the alternatives.

Dynamic Methods can be garbage-collected while methods built with the alternatives cannot be unloaded once loaded into the app-domain.

We don't need to write code to build modules, types etc.; instead, we can just write code for Dynamic Methods, and .NET takes care of the rest.

The code to generate a dynamic method invoking a no-argument instance method of a specific type would look something like below. (Assume the delegate MethodInvoker is already declared as public delegate object MethodInvoker(object target);.)

If you are already familiar with CIL, the code for the dynamic method should be instantly straightforward. If not, you can consult the abundance of documentation about CIL on the Internet. You only need to do this if you want to understand the fine-grain implementation details of Fasterflect. If you only need to use the library effectively, or simply want to have enough information to make the decision to use it or not, the highlights so far on the implementation details should be more than sufficient. That said, let's explore the APIs provided by Fasterflect and observe the improved performance it brings about.

The APIs

Before exploring the APIs provided by Fasterflect, let's first look at the class we will use to perform reflective invocations on the Person class. There is nothing fancy about this class; it is just a POCO with a bunch of static and/or instance constructors, fields, properties, methods, and indexers.

Fasterflect provides two flavors of API, each with pros and cons. (In fact, there are three APIs, but the third one is not a commonly used API - check out the library code documentation for details on this instead.)

The first API is the Default API. This API comprises of a bunch of extension methods for System.Type and System.Object. The benefit of this API is that it is very easy to use. The downsize is that while this API is just the wrapper over the dynamic method generation approach described in the previous section, it is just only 6-10 times faster than normal .NET Reflection invocations. The reason is that there are a number of indirections going on between the API and the invocation on the dynamic method. This is an inevitable cost of having a wrapper API, but it is obviously an area subject to further optimization in upcoming versions of Fasterflect.

Let's explore this API via some code demonstration. I have included a lot of comments to replace the otherwise verbose text narrative.

The second API is called the Cache API and is a little bit more verbose to use, but offers huge gain in performance (usually, a few hundred times faster than normal Reflection calls). The idea is that you can get a direct handle to the returned delegate generated by a dynamic method and keep reusing it instead of going through many layers of indirection (as in the default API). Below is how you can use the Cache API.

Performance

I built an application to show the benchmark of invocations (including constructors, fields, properties, methods, and indexers) for each of the following invocation types: direct, built-in .NET Reflection, Fasterflect Default API, and Fasterflect Cache API. You can check out the full code for the benchmark application in the source code download. In this article, I only list the code for constructor invocation benchmark and method invocation benchmark.

The result for the above benchmark is as follows. The key highlights of the result are:

It only takes a few milliseconds for Fasterflect to build a dynamic method. And, this needs doing only once per application for each field, method, constructor, property, or indexer. The dynamic method is reused by Fasterflect in subsequent calls.

When repeating the same invocation for a considerable number of times (2 million times), the performance of the Default API and Cache API is about 6-10 times and 200-400 times faster than the performance of the built-in .NET Reflection API, respectively.

Conclusion

Fasterflect allows you to perform reflective invocations on constructors, indexers, instance and static fields, methods, and properties. You should select among its two APIs, one optimized for simplicity and one for performance, depending on your particular needs. With this article, I hope I have provided you with enough information to decide whether this library can be of some use to you and enough examples for you to start using this library.

We have implemented the ability to easily look-up members in Fasterflect. The latest code is available here: http://fasterflect.codeplex.com/SourceControl/list/changesets[^]. We're making Fasterflect 2.0 release within a week or two, you can also wait to get the prebuilt binaries instead of building the solution yourself.

Regarding the 1st request, did you mean that you want to specify return type, among others necessary information like method name and parameter types? We suppose so, because return type alone will almost always result in a number of methods and Fasterflect won't know which you want to invoke. Let us know.

You may also want to checkout the Typed Reflector[^] from kzu for ideas on achieving type safety using generics when calling into the dynamically generated code.
Extension methods can sweeten the syntax. Checkout NAom2[^] on Google code for ideas on this.

Hi! Thanks for the suggestion. In fact, I did think about using the technique described the 1st link for type-safe naming but decided not to; I coded those overloads and then removed them from the beta. The problem is that having such type-safety would require the calling call to pass the type parameter to either the class or method, while in most reflection scenarios, people do not know that specific type until runtime. If people already know the type at compile-time, I suppose it's better they just perform direct invocation. Or do I miss anything? (The 2nd link seems to point to an interesting idea, I'll look more into it.) Thanks again!

Luc Pattyn [Forum Guidelines][My Articles]The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.

You're article has been edited by CP staff. You can still:
- get the HTML from it
- edit that
- and mail it in to "submit at codeproject dot com"
and they will replace it.

Luc Pattyn [Forum Guidelines][My Articles]The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.

At 2nd thought about all the changes need doing to accommodate the name change (update this article, change, commit all source code, re-gen code documentation, update CodePlex project page etc.), I decided not to. Keep this naming idea in mind for the next library instead . Thanks for the suggestion again.

Luc Pattyn [Forum Guidelines][My Articles]The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.

I've done something like this with DynamicMethods for personal use, primarily to invoke methods dynamically (doh!), but then I added the rest of the functionality for fun.

Your implementation looks pretty streamlined, really nice.

A few small things to note however: it fails on parameterlessly constructing a struct, there's no option to invoke explicit interface implementations, and it doesn't find methods with ref/out parameters.

Otherwise, great job!

"Have you heard about the object-oriented way to become wealthy?"
"No..."
"Inheritance."

Option to invoke explicit interface implementation is also available in the latest code (http://fasterflect.codeplex.com/SourceControl/list/changesets[^]). Sample usage of this feature can be seen in Invocation/MethodTest.cs#TestInvokeExplicitlyImplementedMethod(). We're making a 2.0 release within a week or two, so stay tuned in case you don't want to build from source.