UnityContainer Performance test results
As part of a basic presentation on unity i have created the following console application (kinda lengthy):
IUnityContainer container = new UnityContainer();
container.RegisterType<ISimpleClass, SimpleClass>();
container.RegisterType<ISingletonWithUnity, SingletonWithUnity>(new ContainerControlledLifetimeManager());
double N = 10000;
double sum = 0;
Console.WriteLine("Testing performace of a basic new object");
for (int i = 0; i < N; i++)
{
DateTime start = DateTime.Now;
ISimpleClass simpleClass = new SimpleClass();
DateTime end = DateTime.Now;
sum += (end - start).Milliseconds;
}
double average = sum/N;
Console.WriteLine("Average time for basic new object is: " + average);
Console.WriteLine("Testing performance of transient resolve using unity");
sum = 0;
for (int i = 0; i < N; i++)
{
DateTime start = DateTime.Now;
ISimpleClass simpleClass = container.Resolve<SimpleClass>();
DateTime end = DateTime.Now;
sum += (end - start).Milliseconds;
}
average = sum / N;
Console.WriteLine("Average time for transient resolve using unity is: " + average);
Console.WriteLine("Testing performance of basic singleton");
sum = 0;
for (int i = 0; i < N; i++)
{
DateTime start = DateTime.Now;
BasicSingltonClass basicSingltonClass = BasicSingltonClass.Instance;
DateTime end = DateTime.Now;
sum += (end - start).Milliseconds;
}
average = sum / N;
Console.WriteLine("Average time for basic singleton is: " + average);
Console.WriteLine("Testing performance of unity singleton");
sum = 0;
for (int i = 0; i < N; i++)
{
DateTime start = DateTime.Now;
SingletonWithUnity singletonWithUnity = container.Resolve<SingletonWithUnity>();
DateTime end = DateTime.Now;
sum += (end - start).Milliseconds;
}
average = sum / N;
Console.WriteLine("Average time for unity singleton is: " + average);
The classes used in the test are pretty straight forward:
- SimpleClass is just an empty class
- BasicSingletonClass is exactly what it is using the usual Double Checked Locking on the instance getter.
- SingletonWithUnity is also just an empty class bu开发者_如何学Pythont as you can see it is registered with the ContainerControlleredLifetimeManager.
The results i'm getting as N goes higher (up to 1 million) are showing that using unity is actually much slower then not using it. I used to think that Unity had some sort of caching of resolves and such to make it much more faster, especially in transient resolve.
Here's an example of a result of running the performance test application when N is set to 10,000:
Testing performace of a basic new object Average time for basic new object is: 0.0007
Testing performance of transient resolve using unity Average time for transient resolve using unity is: 0.008
Testing performance of basic singleton Average time for basic singleton is: 0.0012
Testing performance of unity singleton Average time for unity singleton is: 0.0033
Press any key to continue . . .
As you can see using Unity is a performance impact. I would like to get your honest opinions on whats going on behind the scenes to explain these results.
Thanks in advance!
Keep in mind that Unity must locate the appropriate concrete class for the interface, and then if its found, construct it. Even cacheing the resolve doesn't change the fact that there's an extra method call and (possibly cached) look-up over just newing up the object yourself.
Unity isn't really intended to increase object creation performance. It's intended to provide a robust DI container that can help reduce coupling and ease testing of your code.
Maybe it's interesting to give a theoretical explanation, but in practice this will never be a problem. I can hardly imagine that resolving your classes is the bottleneck in your program. You should only improve performance when it's necessary, not beforehand!
精彩评论