C# Dynamic Object Creation Performance

Recently I had to task to create a dynamic object creation factory in C#. So I thought I test all the options I have to check what performs best.

I also wanted to check the performance implications these options have with the number of parameters in the constructor.

The Options

  1. new T() – Using the new/constructor method to
    instantiate objects
  2. Activator.CreateInstance(typeof(T)) – Using the Activator class to instantiate objects
  3. ConstructorInfo.Invoke() – Using the constructor info reflection class to instantiate objects
  4. Func<T>() – Using compiled lambda expressions to instantiate objects

The Test

I ran some tests to see calculate how each of the techniques mentioned above perform. The tests were the following.

  1. Instantiate a class with 0 constructor parameters.
  2. Instantiate a class with 1 constructor parameters.
  3. Instantiate a class with 2 constructor parameters.
  4. Instantiate a class with 3 constructor parameters.
  5. Instantiate a class with 4 constructor parameters.
  6. Instantiate a class with 5 constructor parameters.

A million (1,000,000) times.

The test Classes

public class A0 {
 public A0() {}
}

public class A1 {
 public A1(object a) {}
}

public class A2 {
 public A2(object a, object b) {}
}

public class A3 {
 public A3(object a, object b, object c) {}
}

public class A4 {
 public A4(object a, object b, object c, object d) {}
}

public class A5 {
 public A5(object a, object b, object c, object d, object e) {}
}

The tests

var a0c = typeof(A0).GetConstructor(new Type[] {});
var a1c = typeof(A1).GetConstructor(new Type[] {
 typeof(object)
});
//...

ParameterExpression paramA = Expression.Parameter(typeof(object), "a");
ParameterExpression paramB = Expression.Parameter(typeof(object), "b");
//...

Func < A0 > a0l = Expression.Lambda < Func < A0 >> (Expression.New(a0c)).Compile();

Func < object, A1 > a1l = Expression.Lambda < Func < object, A1 >> (Expression.New(a1c, new [] {
 paramA,
}), paramA).Compile();
//...

for (int i = 0; i < ITERATIONS; i++) {
 new A0();
}

for (int i = 0; i < ITERATIONS; i++) {
 new A1(new object());
}
//...

for (int i = 0; i < ITERATIONS; i++) {
 Activator.CreateInstance(typeof(A0));
}
for (int i = 0; i < ITERATIONS; i++) {
 Activator.CreateInstance(typeof(A1), new object());
}
//...

for (int i = 0; i < ITERATIONS; i++) {
 a0c.Invoke(new object[] {});
}
for (int i = 0; i < ITERATIONS; i++) {
 a1c.Invoke(new object[] {
  new object()
 });
}
//...

for (int i = 0; i < ITERATIONS; i++) {
 a0l();
}
for (int i = 0; i < ITERATIONS; i++) {
 a1l(new object());
}
//...

The Results

Parameters 			 Elapsed MS  		 Elapsed Ticks

 ***** Create With New ***** 
0 Parameters 			 16  			  59990
1 Parameters 			 33  			  119313
2 Parameters 			 39  			  143419
3 Parameters 			 55  			  201836
4 Parameters 			 40  			  146842
5 Parameters 			 50  			  183507

 ***** Create With Activator ***** 
0 Parameters 			 51  			  185691
1 Parameters  			 790  			  2850419
2 Parameters  			 872  			  3145864
3 Parameters  			 965  			  3480102
4 Parameters  			 1109  			  4000650
5 Parameters  			 1186  			  4277491

 ***** Create With Constructor Info ***** 
0 Parameters 			 122  			  440423
1 Parameters 			 192  			  693479
2 Parameters 			 254  			  917203
3 Parameters 			 311  			  1123222
4 Parameters 			 366  			  1322253
5 Parameters 			 426  			  1537764

 ***** Create With Compiled Lambda ***** 
0 Parameters 			 10  			  38864
1 Parameters 			 15  			  55366
2 Parameters 			 21  			  76782
3 Parameters 			 28  			  101073
4 Parameters 			 36  			  131948
5 Parameters 			 51  			  184227

Conclusion

There is a major performance hit on Activator.CreateInstance() and ConstructorInfo.Invoke(), as soon as constructors start accepting parameters.

You can get away with using Activator.CreateInstance if you are application is independent on the performance of the creation of dynamic objects.

However…

If you application heavily relies on the performance of the creation of dynamic objects, it is advisable to use Compiled lambda expression instead of anything else.

Creating objects using compiled lambda performs as BETTER!?!?!? than the new()/constructor.

Leave a Reply

Your e-mail address will not be published. Required fields are marked *

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