Home > DLR > Comparing method invocation using reflection and dynamic

Comparing method invocation using reflection and dynamic

In C# 4.0, the ‘dynamic’ keyword was added to specify that you don’t want compile time checking – all operations on an instance declared as ‘dynamic’ will be resolved at runtime. This doesn’t add any functionality that wasn’t possible before, as you could use reflection or LCG to accomplish this, but the syntax is much more natural to use and feels like the duck typing you would have in a typical dynamic language.

So what’s the cost in terms of performance? With a little benchmarking, I’ve found that there is a cost to using dynamic, but it’s certainly much faster than invoking methods using reflection. Compiled code, as you would expect, is clearly the fastest way to invoke methods. In my quick little benchmark I was able to invoke the same method about 75 times more often in a two second period using compiled code than using reflection. Compiled is still faster than dynamic – I could invoke the method about 6 times more often in code using compiled invocation than using dynamic. More surprising is the method could be invoked using dynamic about 12 times more often than using reflection.

Here are some numbers from one of my samples – I’m counting the number of times I could invoke the same method in a two second period using all three types of invocation running simultaneously to avoid environmental factors skewing results. Bigger is better – that means the method could be invoked faster.

Compiled: 159,277,840.00 method calls.
Reflection: 2,102,121.00 method calls.
Dynamic: 24,702,097.00 method calls.

What this tells me is whenever I can choose between reflection and dynamic for invoking a method, dynamic is quite likely to perform better.

Here is the source, in case you want to run a similar comparison on your own.

class Program
{
    class MyTest
    {
        public ulong SomeField;

        public void Increment()
        {
            SomeField = checked((ulong)(SomeField + 1));
        }
    }

    static void Main(string[] args)
    {
        // Do any possible setup here so we're only invoking methods during the test.
        MyTest testCompiled = new MyTest();
        MyTest testReflection = new MyTest();
        dynamic testDynamic = new MyTest();
        Type t = typeof(MyTest);
        MethodInfo incrementMethod = t.GetMethod("Increment");

        // Define the ThreadStart for method invocation using compiled, reflection, and dynamic.
        ThreadStart threadStartCompiled = new ThreadStart(() =>
            {
                while (true)
                {
                    testCompiled.Increment();
                }
            });
        ThreadStart threadStartReflection = new ThreadStart(() =>
            {
                while (true)
                {
                    incrementMethod.Invoke(testReflection, null);
                }
            });
        ThreadStart threadStartDynamic = new ThreadStart(() =>
            {
                while (true)
                {
                    testDynamic.Increment();
                }
            });

        // Setup the threads and start them.
        Thread compiledTestThread = new Thread(threadStartCompiled);
        Thread reflectionTestThread = new Thread(threadStartReflection);
        Thread dynamicTestThread = new Thread(threadStartDynamic);
        compiledTestThread.Start();
        reflectionTestThread.Start();
        dynamicTestThread.Start();

        // Wait a couple of seconds to let each thread run then abort them all.
        Thread.Sleep(2000);
        compiledTestThread.Abort();
        reflectionTestThread.Abort();
        dynamicTestThread.Abort();

        // Get the output
        Console.WriteLine("Compiled: {0:n} method calls.", testCompiled.SomeField);
        Console.WriteLine("Reflection: {0:n} method calls.", testReflection.SomeField);
        Console.WriteLine("Dynamic: {0:n} method calls.", testDynamic.SomeField);
    }
}
Advertisements
Categories: DLR
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: