Fastest way to create instance of a Type in Runtime C#

Fastest way to create instance of a Type in Runtime C#

When working with refactoring and loading and creating instances of types in run time using c# the important factor you should take care of is the performance and time needed to create this instance.

we always need to create objects of a type and we should use the method that will not take too much time to create this object.

In this thread, I am going to explain the most famous ways to do this and we will see the performance for each method.

Our targeted classes

First we have two classes X and Y as following:

public class X : baseClass<X>
{
    public X() { }
    public X(int z) { this.Z = z; }
    public int Z;
}

public class Y : X 
{
    public Y() { }
    public Y(int z) : base(z) { }
}

First Method using direct method NEW()

static void CreateWithNew(int t)
{
    var stopwatch = new Stopwatch();
    stopwatch.Start();
    for (int i = 0; i < t; i++)
    {
        var r1 = new X();
        var r2 = new Y();
    }
    stopwatch.Stop();
    Console.WriteLine("{0}, {1}", stopwatch.Elapsed, "NEW()");
}

Second Method using refactoring with Activator.CreateInstance

static void CreateWithActivator(int t)
{
    var stopwatch = new Stopwatch();
    stopwatch.Start();
    for (int i=0;i<t; i++)
    {
        var r1 = Activator.CreateInstance(typeof(X)) as X;
        var r2 = Activator.CreateInstance(typeof(Y)) as Y;
    }
    stopwatch.Stop();
    Console.WriteLine("{0}, {1}", stopwatch.Elapsed, "Activator.CreateInstance");
}

Third Method using Invoking of the constructor

static void CreateWithConstractor(int t)
{
    var stopwatch = new Stopwatch();
    stopwatch.Start();
    for (int i = 0; i < t; i++)
    {
        var r1 = GetNewObject(typeof(X)) as X;
        var r2 = GetNewObject(typeof(Y)) as Y;
    }
    stopwatch.Stop();
    Console.WriteLine("{0}, {1}", stopwatch.Elapsed, "InvokeConstractor");
}
public static object GetNewObject(Type t)
{
    try
    {
        return t.GetConstructor(new Type[] { }).Invoke(new object[] { });
    }
    catch
    {
        return null;
    }
}

Forth Method using compiled expressions

static void CreateWithCompiledExpression(int t)
{
    var stopwatch = new Stopwatch();
    stopwatch.Start();
    for (int i = 0; i < t; i++)
    {
        var r1 = XCreator() as X;
        var r2 = YCreator() as Y;
    }
    stopwatch.Stop();
    Console.WriteLine("{0}, {1}", stopwatch.Elapsed, "CompiledExpression");
}
static readonly Func<X> XCreator = Expression.Lambda<Func<X>>(
   Expression.New(typeof(X).GetConstructor(Type.EmptyTypes))
 ).Compile();

static readonly Func<Y> YCreator = Expression.Lambda<Func<Y>>(
   Expression.New(typeof(Y).GetConstructor(Type.EmptyTypes))
 ).Compile();

Fifth and my lovely method using Clone

to use clone the classes should implement the IClonable interface

static void CreateWithClone(int t)
{
    var stopwatch = new Stopwatch();
    X x = new X();
    Y y = new Y();
    stopwatch.Start();
    for (int i = 0; i < t; i++)
    {
        var r1 = x.Clone() as X;
        var r2 = y.Clone() as Y;
    }
    stopwatch.Stop();
    Console.WriteLine("{0}, {1}", stopwatch.Elapsed, "Clone");
}

So we implemented IClonable interface  in the base class like that :

public class baseClass<T> : ICloneable where T : new()
{
    public object Clone()
    {
        return default(T);
    }
}
public class X : baseClass<X>
{
    public X() { }
    public X(int z) { this.Z = z; }
    public int Z;
}

public class Y : X 
{
    public Y() { }
    public Y(int z) : base(z) { }
}

Main Method:

static void Main(string[] args)
{
    int countOfTest = 10000;
    Console.WriteLine("count Of Tests : " + countOfTest);
    CreateWithNew(countOfTest);
    CreateWithActivator(countOfTest);
    CreateWithConstractor(countOfTest);
    CreateWithCompiledExpression(countOfTest);
    CreateWithClone(countOfTest);

    Console.ReadLine();
}

Results

As we can see cloning is the fastest way to create new instance of each type, and therefore we should create on instance for each type first and use this instance to clone it later, we may lose time for retrieving  this saved instance , but we can manage this retrieving time with many ways.

about the parameterized constructor we should allow a default constructor without any arguments and later we can config the object.

Also I found that Activator.CreateInstance perform well in small tests like the following

References : https://stackoverflow.com/questions/752/get-a-new-object-instance-from-a-type

Best Regards

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.