Create Object Instances Faster Than Reflection

An example screenshot of the Test

Everybody knows that Reflection is a really very important topic in .NET. So I won’t repeat the importance of it, it is an unquestionable subject; besides, I have to admit that it saved my life too  many times.

But like every good thing Reflection has also some disadvantages, too. One of the important disadvantages of the Reflection is performance.

Actually, if we talk about considering a few reflection operations, there won’t be any performance problem because Reflection is not slow. It is just slower than the other ways which make us do the same operations. For example:

// WAY 1 normal instance creation 
ArrayList list = new ArrayList();

// WAY 2 Using reflection to create an instance of a type
ArrayList list = (ArrayList)typeof(ArrayList).GetConstructor(Type.EmptyTypes).Invoke(null);

If we call the methods above not too many times at the same time, there won’t be any performance problem but there might be a performance problem if we call this reflection example too many times in any iteration as for, while, foreach etc. For example:

Stopwatch watch = new Stopwatch();
Type t = typeof(ArrayList);
ConstructorInfo info = t.GetConstructor(Type.EmptyTypes);

object o = null;
ArrayList list = null;
watch.Start();
for (int i = 0; i < 1000000; i++)
{
    list = new ArrayList();
}
watch.Stop();
Console.WriteLine(string.Format("new : {0} ms", watch.ElapsedMilliseconds));

GC.Collect();

o = null;Rr
watch.Start();
for (int i = 0; i < 1000000; i++)
{
    o = info.Invoke(null);
}
watch.Stop();
Console.WriteLine(string.Format("Reflection : {0} ms", watch.ElapsedMilliseconds));

When you run the code above, the output will be as follows:
new : 23 ms
Reflection : 1131 ms

As you see in the above example, if you use Reflection to create too many items, it will work very slowly. If we talk about the first method (using new), we can only use it when we know the object’s Type during the coding time. Otherwise, we cannot use the new keyword to create an instance of an unknown type. In the world of programming, this is a very common situation because we usually don’t know the actual type during the coding, so we have to use Reflection in those scenarios to create instances of a Type.

There are two different ways to make this code run faster. One of them is using Activator class to create object instances of Types. If we want to use the Activator class in the above example to create an instance of an object, the code will be as runs:

o = null;
watch.Start();
for (int i = 0; i < 1000000; i++)
{
   o = Activator.CreateInstance(t);
}
watch.Stop();
Console.WriteLine(string.Format("Activator : {0} ms", watch.ElapsedMilliseconds));

If we execute this code, we’ll get the following result:

Activator : 207 ms.

However, this is not the best way. Yes, this is fast but there is also another way which run faster than the Activator class.
The last method I mention is using DynamicMethod method. Dynamic method is a method which we instantiate it in the runtime at the memory, and works as any method we wrote in our programs.

// Class which creates a dynamic method for the given type
 
public class ObjectCreateMethod
{
    delegate object MethodInvoker();
    MethodInvoker methodHandler = null;

    public ObjectCreateMethod(Type type)
    {
        CreateMethod(type.GetConstructor(Type.EmptyTypes));
    }

    public ObjectCreateMethod(ConstructorInfo target)
    {
        CreateMethod(target);
    }

    void CreateMethod(ConstructorInfo target)
    {
        DynamicMethod dynamic = new DynamicMethod(string.Empty,
                    typeof(object),
                    new Type[0],
                    target.DeclaringType);
        ILGenerator il = dynamic.GetILGenerator();
        il.DeclareLocal(target.DeclaringType);
        il.Emit(OpCodes.Newobj, target);
        il.Emit(OpCodes.Stloc_0);
        il.Emit(OpCodes.Ldloc_0);
        il.Emit(OpCodes.Ret);

        methodHandler = (MethodInvoker)dynamic.CreateDelegate(typeof(MethodInvoker));
    }

    public object CreateInstance()
    {
        return methodHandler();
    }
}
ObjectCreateMethod inv = new ObjectCreateMethod(info);
o = null;
watch.Start();
for (int i = 0; i < 1000000; i++)
{
    o = inv.CreateInstance();
}
watch.Stop();
Console.WriteLine(string.Format("Method Invocation : {0} ms", watch.ElapsedMilliseconds));

When we run the code above, the output will be as follows:
Method Invocation : 27 ms.

Here in this example, we are creating an instance of DynamicMethod and fill DynamicMethod’s body by using ILGenerator class. And in the IL, we use the Newobj-(Argument: Method Token)- OpCode (which means creating an instance of a Type) to create an instance, and than we return the created object to the caller. This is also what the new keyword does in the IL. So our performance will be as the same as the new keyword’s performance. Also to use the DynamicMethod, we used CreateDelegate method of the DynamicMethod, which creates a new delegate which we can use to execute this method. By calling CreateInstance method in the  ObjectCreateMethod class, our DynamicMethod is invoked and returns the result.

Finally as you see here, if you use DynamicMethod to create instances of a Type (if you don’t know the exact type during coding, otherwise you can use new 🙂 ) is the fastest way to create an instance of the object.

You don’t need to write your own Dynamic method creator classes, you can use the ObjectCreateMethod instances in your applications. Of course this method is just for the constructors which has no parameters. If you want to run a constructor which takes parameters, then you have to write your own Dynamic Methods.

See you later …

  More about Dynamic Methods

Share: