Activator.CreateInstance Performance

Writing

Update: It appears that the access modifiers on “TestClass” affect the performance of “Activator.CreateIntance”. My bet would be due to access checks of some sort. If “TestClass” is internal (which C# classes default to if there is none specified) then the results are the opposite of what you see below, however if the “TestClass” is public then the results are as you see below. I will update with more info when I explore this a bit further…

I was doing a bit of performance comparisons since there has been a bit of talk around the performance of reflection flying around here. My general opinion on this topic is that while reflection is expensive, it is a lot cheaper than programmers. 🙂 I have found that the places where reflection helps out are often places where there really is no other option.

But anyways, so I was just getting a few numbers comparing Activator.CreateInstance to just using the “new” operator and I came away with this:

image

For 1 million instantiations, I was coming away with 7ms for the “new” operator and about 1.5 seconds for “CreateInstance”. While this is a huge difference in performance, you must ask yourself, how many instantiations through reflection will my application be doing? If the number is millions per second, then you might have an issue. 🙂

The interesting tidbit that I noticed through was when I decided to go ahead and use the non-generic version of “CreateInstance”. I had used the generic version because that is generally my fallback. When I ran the tests with the non-generic version, the results were surprising:

image

The non-generic version ran about 8 times faster, and that is including the cast to get it to the type I requested. I wondered why the performance varied so much, since I would assume that the generic version of “CreateInstance” just looked like this:

public T CreateInstance<T>()
{
    return (T) CreateInstance(typeof (T));
}

So I fired up my old friend, Reflector, and started looking at the implementation of both methods. The non-generic version of “CreateInstance” casts the Type.UnderlyingSystemType to a “RuntimeType” and then calls “CreateInstanceImpl” on the “RuntimeType”. The generic version calls “RuntimeTypeHandle.CreateInstance”. I’m honestly not sure what the implications of using one versus the other (well, other than speed), but if anyone out there does have a clue, could I borrow it?

Hope this helps out someone.

And just for fun, here is the code I used to run the tests:

Stopwatch sw = new Stopwatch();

sw.Start();
for (int i = 0; i < 1000000; i++)
{
    var testClass = new TestClass();                
}
sw.Stop();
Console.WriteLine("new operator: " + sw.ElapsedMilliseconds);

sw.Reset();
sw.Start();            
for (int i = 0; i < 1000000; i++)
{
    var testClass = Activator.CreateInstance<TestClass>();
}            
sw.Stop();
Console.WriteLine("Activator.CreateInstance<T>(): " + sw.ElapsedMilliseconds);

         
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000; i++)
{
    var testClass = (TestClass)Activator.CreateInstance(typeof(TestClass));
}
sw.Stop();
Console.WriteLine("Activator.CreateInstance(Type type): " + sw.ElapsedMilliseconds);

Loved the article? Hated it? Didn’t even read it?

We’d love to hear from you.

Reach Out

Comments (10)

  1. Hi,

    The real performance hit when using Reflection is when we are retrieving the tree structure of an object. This contains getting all the properties and then getting the properties of the properties and so on.

  2. @Duncan,

    >> Why?

    Because you will traverse the new object tree again and find all child for that object. Then you will traverse the child of that object and so on.

    This becomes a long chain of traversal down the tunnel invoking every object type.

  3. hi,Justin Etheredge,I run your code again,but i get diference with your test result.generic version is faster than non-generic version,so why?

  4. @leo I thought that the only difference could be in "TestClass", because that is the only code I didn’t post, and it turns out that I was correct. On my machine, if "TestClass" is internal then the generic version runs in about a second, while the non-generic version takes about 3 seconds. If the class is public then the results are as you see in the above post. Interesting results, and maybe since I am now a C# MVP I’ll have to inquire about it. 🙂

  5. @Mohammad

    >> This becomes a long chain of traversal down
    >> the tunnel invoking every object type.

    As Duncan pointed out caching is the solution. Provided you have sufficient memory, at most, you only ever need to use reflection once, making the performance penalty negligible beyond initialization or first-use.

    As an example, consider the example of using Activator in this post, if you combined caching and the run-time generation of byte code using emit, every object constructed using reflection, after the first, would be as efficient as using "new" operator, at least up to the efficiency of the data structure you used for caching.

  6. Interesting article.
    I had used this extensivly in our application, and it would seem swapping to a non-generic version would have had a big impact on performance.

Leave a comment

Leave a Reply

Your email address will not be published.

More Insights

View All