Performance benchmark of Dynamic object instantiation

I have been tinkering around my "home brewed" dependency injection library, as I mentioned in my last post. Since most of the code revolves around instantiating objects (well, and keeping them orderly registered), I figured it couldn't hurt to check out which is the best (i.e. fastest) way to dynamically instantiate objects in .NET.

There are essentially two ways you can register objects to my IoC container: using a delegate or using the type. The delegate is a really nice method, also used by Autofac (any comparison between my library and Autofac is probably an insult to Autofac  :)). It works like this:

container.Register(c => new Implementor());

In this case the delegate simply instantiates an instance of a class that implements the IInterface interface. Pretty slick and also very fast: calling the delegate is exactly one method call slower than calling the new operator, so that shouldn't be a problem at all.

Problem is, sometimes you can't register a delegate (for instance when you're registering dynamically loaded plug-ins to the container). In that case you need to manually instantiate the objects: .NET provides a lot of different ways to do that, and some methods can be compiled to dynamic methods or to delegates which probably should improve their performance.

There's a pretty complete blog post by Haibo Luo, but it's 5 years old and might not be accurate (it also misses the methods that use System.Linq.Expressions).

Benchmark

I threw some code together (source code) that instantiates 10.000 objects with each of the following methods and returns the elapsed time:

Direct instantiation

This is actually the simplest one, just for reference:

var tmp = new MyClass();

Since many articles boast that object instantiation in .NET is incredibly fast, I'd like to know how fast it really is.

Activator

This is also a method that has been around since .NET 1.0 and seems to be simple and well optimized.

var tmp = (MyClass)Activator.CreateInstance(typeof(MyClass));

There's a generic version as well:

var tmp = Activator.CreateInstance<MyClass>();

Invoking the constructor

By using reflection we can extract a reference to the default constructor of our class and invoke it dynamically:

var cInfo = typeof(MyClass).GetConstructor(Type.EmptyTypes);
//...
var tmp = (MyClass)cInfo.Invoke(null);

Compiling the constructor invokation

Using .NET's code generation classes we can actually compile the code above to a dynamic method (in a dynamic in-memory assembly) and run that code instead. That should be - intuitively - as fast as the direct new() call.

AssemblyBuilder asmBldr = AppDomain.CurrentDomain.DefineDynamicAssembly(
	new AssemblyName("InMemory"), AssemblyBuilderAccess.Run);
ModuleBuilder modBldr = asmBldr.DefineDynamicModule("helper");
TypeBuilder typeBldr = modBldr.DefineType("ClassFactory");

//Build a static factory method
MethodBuilder methBldr = typeBldr.DefineMethod(typeof(MyClass).Name,
	MethodAttributes.Public | MethodAttributes.Static, typeof(MyClass), Type.EmptyTypes);
ILGenerator ilgen = methBldr.GetILGenerator();
ilgen.Emit(OpCodes.Nop);
ilgen.Emit(OpCodes.Newobj, typeof(MyClass).GetConstructor(Type.EmptyTypes));
ilgen.Emit(OpCodes.Ret);

//Get a reference to the new dynamic method
Type baked = typeBldr.CreateType();
MethodInfo mi = baked.GetMethod(typeof(MyClass).Name);

//...
var tmp = (MyClass)mi.Invoke(null, null);

That dynamic invocation on MethodInfo doesn't look all too fast. To improve that, we can invoke that method as a delegate instead:

var miDelegate = (Func<MyClass>)Delegate.CreateDelegate(typeof(Func<MyClass>), mi);
//...
var tmp = miDelegate();

Using Linq.Expressions

With the power of Linq we can build an expression with a single new() operation and compile that (instead of doing all the dynamic assembly writing above).

NewExpression constrCall = Expression.New(typeof(MyClass));
var lambda = Expression.Lambda(constrCall);
var constrDelegate = lambda.Compile();
//...
var tmp = (MyClass)constrDelegate.DynamicInvoke();

That too can be cast to a generic delegate and then be called directly:

NewExpression constrCall = Expression.New(typeof(MyClass));
var lambda = Expression.Lambda>(constrCall);
var constrDelegate = lambda.Compile();
//...
var tmp = constrDelegate();

The results

The benchmark results

The bars with dark colors are the generic methods, that take a statically compiled type definition. The lighter bars are fully dynamic methods.

So: object instantiation via new() is actually very fast. 1.6 milliseconds for 10.000 objects is pretty good, I suppose.  :) Dynamically calling a method is always a bad idea: both using a Linq Expression and using a dynamically generated Assembly are very slow if you cannot convert the method call to a statically typed delegate (which I cannot do in my case). On the other hand, if you can it's awesome: practically as fast as direct instantiation.

Invoking the constructor isn't bad at all (much better than dynamically invoking a method), but using Activator.CreateInstance appears to be the best choice nonetheless. The article mentioned before actually suggests that Activator contains some special optimization and caches the last 16 instantiated types.

Surprisingly, the generic Activator.CreateInstance<T> is way slower than the non-generic one.

In conclusion: I'm going to stick with Activator since it seems the "standard" way of doing things and is quite fast without requiring any code from my side (and that's just great)!