Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 6,125 | Comments: 45,488

filter by tags archive

Creating objects - Perf implications

time to read 23 min | 4569 words

Here are a few examples of how we can create objects, and the perf implications of each way. In all those tests, I have used the following class as my benchmark.

public class Created
    public int Num;
    public string Name;
    public Created(int num, string name)
        this.Num = num;
        this.Name = name;

We have a value type and a reference type that are passed to the constructor.

The test code is here:

static void Main(string[] args)
    int iterations = 1000000;
    Stopwatch watch = Stopwatch.StartNew();
    for (int i = 0; i < iterations; i++)

Here it my base line, calling the constructor directly.

private static Created CreateInstance(int i)
    return new Created(i, i.ToString());

This executes in 00.3648117 seconds on severely underpower laptop. Pretty good, considering we just created a million instances. Now, let us see what happens if we user Activator, shall we?

private static Created CreateInstance(int i)
    return (Created)Activator.CreateInstance(
                        typeof(Created), i, i.ToString());

This run depressingly slow, 06.8242636 seconds.

Let us try to improve that a bit, using GetUninitializedObject and directly invoking the constructor.

static ConstructorInfo ctor = typeof(Created).GetConstructors()[0];
private static Created CreateInstance(int i)
    object o = FormatterServices.GetUninitializedObject(typeof(Created));
    return (Created)ctor.Invoke(o, new object[]{i, i.ToString()});

This runs in 03.2422335 seconds, a significant improvement, but we can do even more, I think.

We start by making the required definitions:

static ConstructorInfo ctor = typeof(Created).GetConstructors()[0];
delegate Created CreateCtor(int i, string s);
static CreateCtor createdCtorDelegate;

Then we generate a dynamic method to create the object, and turn that into a delegate:

DynamicMethod method = new DynamicMethod("CreateIntance", typeof(Created),
    new Type[] { typeof(int), typeof(string) });
ILGenerator gen = method.GetILGenerator();
gen.Emit(OpCodes.Ldarg_0);// i
gen.Emit(OpCodes.Ldarg_1);// s
gen.Emit(OpCodes.Newobj, ctor);// new Created
createdCtorDelegate = (CreateCtor)method.CreateDelegate(typeof(CreateCtor));

Now, in the method itself, all we have to do is call this delegate:

private static Created CreateInstance(int i)
    return createdCtorDelegate(i, i.ToString());

And now that run very fast... 00.4314517 seconds. Almost as fast as our baseline. But this is not really a good example, I am afraid. At least, not a god example of generally creating instances, let us make this into the more general form, shall we?

We will change the CreateCtor delegate to the following signature:

delegate object CreateCtor(object[] args);

And the generation of the dynamic method to use the generic approach:

DynamicMethod method = new DynamicMethod("CreateIntance", typeof(Created),
    new Type[] { typeof(object[]) });
ILGenerator gen = method.GetILGenerator();
gen.Emit(OpCodes.Unbox_Any, typeof(int));
gen.Emit(OpCodes.Castclass, typeof(string));
gen.Emit(OpCodes.Newobj, ctor);// new Created
createdCtorDelegate = (CreateCtor)method.CreateDelegate(typeof(CreateCtor));

We need to make the following modification to our CreateInstance method:

private static Created CreateInstance(int i)
    return (Created)createdCtorDelegate(new object[]{i, i.ToString()});

And now it runs in.... 00.5018288.

Now, what does this long and arcane post tells us?

Creating instances, no matter how many, is really cheap. Remember that I had to do a million iteration to get something measurable.

The table bellow give the final statistics. Pay attention to the last column, this gives the amount of time it take to create a single instance. Even the most hard core perf fanatic would be hard pressed to argue over 0.000007 seconds. At least I hope so :-)

Create single instance Iterations Time Method
0.00000036481170000000 1000000
0.00000682426360000000 1000000
0.00000324223350000000 1000000
0.00000050182880000000 1000000
Dynamic Method

And just to clarify, you are not going to see anything like creating a million object in most scenarios that you care about. In other words, you can probably leave things well enough alone.


Chad Myers

The extra 0.000007 seconds is probably in the call of the delegate, and not in the instance create.

What if you called the delegate directly from the loop instead of calling a func that calls another func?

Ayende Rahien

Which 0.00007 seconds are you talking about? That is the cost of creating an object using Activator.CreateInstance

Chad Myers

Ayende: Oops, I was talkin' about the diff between the Dynamic Method and calling 'new' directly.

The diff/instance of those is 0.0000001370171 seconds

Bill Barry

How would you generate a method to call a constructor which has more than 3 arguments?

Ayende Rahien


I refuse to care about that kind of number. :-)

Bill Barry

I meant with the opcodes:

ILGenerator gen = method.GetILGenerator();

gen.Emit(OpCodes.Ldarg_0);// i

gen.Emit(OpCodes.Ldarg_1);// s

gen.Emit(OpCodes.Newobj, ctor);// new Created

there is:





but there isn't an OpCodes.Ldarg_4. How would you load one with more arguments? I figure those are shortcuts the compiler could use, but you should be able to generate a function which returns a "create instance" delegate with more arguments. I was trying to see if I could write a dynamic method with this signature:

delegate Created CreateCtor(params object[] s);

Ayende Rahien

There is

generator.Emit(OpCodes.Ldarg, 5)

Bill Barry

umm, err, ignore that last comment; that is basically what you did (I was thinking generic referred to .NET Generics).

I feel dumb sometimes.

James Arendt

Another option is available in .NET 3.5. Build a lambda expression tree and compile it into a delegate. No need to write Emit statements as in the dynamic IL approach.

Tor Langlo

Just curious, how long does the "i.ToString()" call take in this test?


Do you have figures when creating transient objects with IoC.Resolve? Just curious..

Jon Skeet

One interesting twist would to be running the same tests, but passing in a constant string. You're not creating 1 million objects here - you're creating at least 2 million.

I haven't run all of your tests, but just the "call the constructor" one: and on my laptop, creating 100 million instances goes down from taking 28.6 seconds to 0.97 seconds when you pass in "x" as the string parameter. Turning off method inlining pushes it up to 1.46 seconds.

In other words, at first sight (and I'm aware that benchmarking is a horribly fiddly business) the actual object creation is only taking about 5% of the time. The rest is the constant hit of converting an integer into a string.

Given that information, I think it's worth rerunning all the tests. Suddenly all the overheads of delegates will look more significant, and Activator.CreateInstance will be an absolute dinosaur - I suspect.

None of this detracts from your point that creating objects is indeed very cheap.

Roger Alsing

I've posted an alternative to these approaches using Linq expression trees:


Mark Seemann

Thank you for teaching me something new today :)

What's the overhead associated with creating the dynamic method?

When you create a million objects, it's probably neglegible, but what if you are only creating a few? Is there a break-even where, below that number of objects, one of the other methods is more efficient, but for a higher number, a dynamic method is the best performer?

Ayende Rahien


Creating a new dyamic method: 00.0012487

Creating a single object using Activator.CreateInstance: 0.0000063033382

I wouldn't worry about it

dominique Gratpain

What about if you use properties (with accessors get/set) instead of public variables (Num and Name) ?

Have you test the same with vb.net ?

I am curious about these two points.


Ayende Rahien

dominique ,

Not really relevant, because it is object creation we are testing.

Adam Tybor

Interesting.... I get Security.VerificationException at run time. I was working on a patch for MicroKernel DefaultActivator and I can't even get your simple code to run. Is it a 3.5 thing?

Operation could destabilize the runtime.

System.Security.VerificationException: Operation could destabilize the runtime.

at CreateIntance(Int32 , String )
Ayende Rahien

That happens when you get the code even slightly wrong

Comment preview

Comments have been closed on this topic.


  1. The design of RavenDB 4.0: Physically segregating collections - 14 hours from now
  2. RavenDB 3.5 Whirlwind tour: I need to be free to explore my data - about one day from now
  3. RavenDB 3.5 whirl wind tour: I'll have the 3+1 goodies to go, please - 5 days from now
  4. The design of RavenDB 4.0: Voron has a one track mind - 6 days from now
  5. RavenDB 3.5 whirl wind tour: Digging deep into the internals - 7 days from now

And 12 more posts are pending...

There are posts all the way to May 30, 2016


  1. The design of RavenDB 4.0 (14):
    03 May 2016 - Making Lucene reliable
  2. RavenDB 3.5 whirl wind tour (14):
    04 May 2016 - I’ll find who is taking my I/O bandwidth and they SHALL pay
  3. Tasks for the new comer (2):
    15 Apr 2016 - Quartz.NET with RavenDB
  4. Code through the looking glass (5):
    18 Mar 2016 - And a linear search to rule them
  5. Find the bug (8):
    29 Feb 2016 - When you can't rely on your own identity
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats