Skip Navigation LinksHome > View Post

Performance of Method.Invoke vs a Delegate

I recently had to use a bit of reflection to call a private method on a third party component (don't ask why, it's complicated but you'll just have to trust me).

Naturally, wherever reflection is used in a server-side application I start to worry a little about performance, which inevitably leads to a bit of micro-perf and premature-optimization but sometimes I just can't help myself. In fact, it's often an educational process as I hope this post demonstrates.

Lets imagine the third party component has a class called ThirdPartyComponent with a static private method SomePrivateMethod that takes no parameters and returns a string.

To make sure that the reflection part only happens once per appdomain I used a static to store the MethodInfo of the private method in question. Here's a snippet of the example wrapper class:

using System;
using System.Reflection;

public class MyWrapper
{
    // this is the 'reflection' bit
    private static MethodInfo _method = typeof(ThirdPartyComponent).GetMethod("SomePrivateMethod", BindingFlags.NonPublic | BindingFlags.Static);

    public string SomePublicMethod()
    {
        // now we can invoke the method using the method info
        // note there are no parameters to pass
        return (string) _method.Invoke(null, null);
    }

}

In performance terms, this compares pretty unfavourably against a plain old method call. Initial performance tests showed that 10,000,000 calls to SomePublicMethod above were taking over 12 seconds compared to calling the same method publicly (I setup stub methods to make the performance more measurable) which took less than 1/10 of a second. Ouch!

It was then that I realised that creating a strongly typed delegate might give us a little more speed...

using System;
using System.Reflection;

public class MyWrapper
{
    // this is the 'reflection' bit
    private static MethodInfo _method = typeof(ThirdPartyComponent).GetMethod("SomePrivateMethod", BindingFlags.NonPublic | BindingFlags.Static);
    
    // This is my delegate with the same signature as the private method
    private delegate string MyDelegate();
    
    // Create an instance of the delegate pointing at our private function
    private static MyDelegate _delegate = (MyDelegate) Delegate.CreateDelegate(typeof(MyDelegate), _method);

    public string SomePublicMethod()
    {
        // invoke the delegate
        return _delegate();
    }

}

Here's the final results for 10,000,000 calls:

Invocation Method Duration (seconds)
Direct Call to Public Method 0.0625
Method.Invoke(null, null) 12.0312
Delegate 0.1093

Whoosh! A significant improvement and well worth the effort, I'm sure you'll agree!

Tags: .NET

 
Josh Post By Josh Twist
2:30 AM
19 Dec 2005

» Next Post: That Agile vs BDUF thing again
« Previous Post: Localizing Site Map data in ASP.NET 2.0

Comments are closed for this post.

Posted by Andrii @ 31 Aug 2011 2:00 PM
What about difference in performance of "if" vs delegate

void a()
{
if(x) b();
else c();
}

vs

Action aa = b;

void a()
{
aa();
}

© 2005 - 2014 Josh Twist - All Rights Reserved.