Justin sent me a snippet for creating a “Fast Activator”. I modified it a little bit to the following:
public delegate T FastActivator<T>() where T : class;
public static FastActivator<T> CreateFastActivator<T>(BindingFlags bindingFlags, params Type[] constructorParameterTypes)
where T : class
{
var type = typeof(T);
var dynamicMethod = new DynamicMethod("___FastActivator" + type.Name, type, null, type);
var ilGenerator = dynamicMethod.GetILGenerator();
var constructor = type.GetConstructor(bindingFlags, null, constructorParameterTypes, null);
ilGenerator.Emit(OpCodes.Newobj, constructor);
ilGenerator.Emit(OpCodes.Ret);
return dynamicMethod.CreateDelegate(typeof(FastActivator<T>)) as FastActivator<T>;
}
public static FastActivator<T> CreateFastActivator<T>()
where T : class
{
return CreateFastActivator<T>(BindingFlags.Public | BindingFlags.Instance);
}
Here’s a chunk of code that compares three methods of instantiating a class:
public static void Time(Action action, string name)
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 1000000; i++)
{
action();
}
sw.Stop();
Console.WriteLine(name + ": " + sw.ElapsedMilliseconds);
}
static void Main(string[] args)
{
FastActivator<MyClass> fast = CreateFastActivator<MyClass>();
Time(() => { MyClass m = Activator.CreateInstance<MyClass>(); }, "Activator");
Time(() => { MyClass m = new MyClass(); }, "Constructor");
Time(() => { MyClass m = fast(); }, "FastActivator");
Console.WriteLine("Done...");
Console.ReadLine();
}
The output on my box:
Activator: 1333
Constructor: 39
FastActivator: 56
That’s a decent performance bump over a simple call to Activator.CreateInstance.