# logchan's Blog

### Optimizing C# reflection method calls

TL;DR: Func<> and Action<> instead of MethodInfo.Invoke runs 50 times faster

I can recall the excitement when I first learnt about reflection in C#. At that time my programming experience was limited to basic VB6 and C, so being able to browse type information was completely new to me. I was shocked and inspired by the possiblities that reflection can bring.

Reflection enables a lot of applications. For example, GameObject.SendMessage in Unity is fulfilled by finding the method with a name via reflection and then invoking it. Another important application is generic serializers. Without reflection, serializing objects will involve the pain of writing similar routines for every class[1]. Generic serializers like XmlSerializer and BinaryFormatter have saved a huge amount of development effort.

[1] Or some messy template and macro magic in C++ - see this StackOverflow answer for more.

However, we may overlook the performance cost as we enjoy the convenience. The rest of this post measures the reflection method calls in C#, and propose an optimization with delegate.

#### The scenario, problem and answer

Assume that you are writing a serializer[2]. You will need to get the property values of the object using reflection, something like:

Intuitively, since getting properties from a class seems time consuming, you will cache the properties of the class:

After some profiling, you will realize that the MethodInfo.Invoke call slowing your serializer down. This is an unfortunate pitfall of reflection - it is slow.

But why is that? Well, each time you call Invoke, it needs to find where the method is via some reflection APIs. With this knowledge in mind, we can find an direction to optimization: is it possible to cache the location of the method?

The answer, if you come from C or C++, is immediately function pointers. In C#, they are Delegates. More specifically, in this case we need Func<,> (or Action<,> if you are deserializing and using setters). The concept shall be fairly simple and can be Googled so I would not go into it. What matters is how to create a delegate from a MethodInfo:

Note that the type of the function pointer must match the method, or an exception will be thrown at run time.

How significant is this optimization? We can run a benchmark.

[2] This can happen. For example, when your boss wishes to avoid the poor performance of BinaryFormatter.

#### Benchmark

We have a data class:

And two ways to get the value of property A (plus a non-reflection one for reference). Each method measures the time to get the value iterations times.

To ensure fairness, only one of the methods is run in each application run:

And, the results:

Method Average Time (ms)
MethodInfo.Invoke 2.0960
Func 0.0380
Direct Get 0.0250

So, yes there is a huge difference between MethodInfo.Invoke and Func… a 50 times difference. Hopefully you know what to do next time you use reflection.

Happy coding!