В рамках базовой презентации по Unity я создал следующее консольное приложение (довольно длинное):
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);
Классы, используемые в тесте, довольно просты:
- SimpleClass - это просто пустой класс
- BasicSingletonClass - это именно то, для чего используется обычная блокировка с двойной проверкой для получателя экземпляра.
- SingletonWithUnity также является пустым классом, но, как вы можете видеть,зарегистрирован в ContainerControlleredLifetimeManager.
Результаты, которые я получаю при увеличении N (до 1 миллиона), показывают, что использование единицы на самом деле намного медленнее, чем его отсутствие.Раньше я думал, что в Unity есть какое-то кэширование разрешений и такое, чтобы сделать его намного быстрее, особенно при переходном разрешении.
Вот пример результата запуска приложения для тестирования производительности, когда N установлено в10 000:
Тестирование производительности базового нового объекта Среднее время для базового нового объекта: 0,0007
Тестирование производительности переходного разрешения с использованием единицы Среднее время для переходного разрешения с использованием единицы: 0,008
Тестирование производительности базового синглтона Среднее время для базового синглтона составляет: 0,0012
Тестирование производительности одноэлементного сингла Среднее время для синглетного единства: 0,0033
Нажмите любую клавишу для продолжения.,.
Как вы можете видеть, использование Unity влияет на производительность.Я хотел бы получить ваше честное мнение о том, что происходит за кулисами, чтобы объяснить эти результаты.
Заранее спасибо!