Posted on 1/5/2009 11:42:02 AM by Justin Etheredge
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:
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:
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);