В нашей игре (предназначенной для мобильных устройств) у нас есть несколько различных типов сущностей, и я пишу фабрику / репозиторий для обработки экземпляров новых сущностей. Каждый конкретный тип сущности имеет собственную реализацию фабрики, и этими фабриками управляет EntityRepository.
Я бы хотел реализовать хранилище как таковое:
Repository
{
private Dictionary <System.Type, IEntityFactory<IEntity>> factoryDict;
public T CreateEntity<T> (params) where T : IEntity
{
return factoryDict[typeof(T)].CreateEntity() as T;
}
}
пример использования
var enemy = repo.CreateEntity<Enemy>();
но я обеспокоен производительностью, особенно связанной с операцией typeof (T) в приведенном выше. Насколько я понимаю, компилятор не сможет определить тип T, и его нужно будет определить во время выполнения с помощью отражения, правильно? Один из вариантов:
Repository
{
private Dictionary <System.Type, IEntityFactory> factoryDict;
public IEntity CreateEntity (System.Type type, params)
{
return factoryDict[type].CreateEntity();
}
}
, который будет использоваться как
var enemy = (Enemy)repo.CreateEntity(typeof(Enemy), params);
в этом случае всякий раз, когда вызывается typeof (), тип находится под рукой и может быть определен компилятором (верно?), И производительность должна быть лучше. Будет ли заметная разница? какие-либо другие соображения? Я знаю, что у меня также может быть такой метод, как CreateEnemy, в хранилище (у нас есть только несколько типов сущностей), который был бы быстрее, но я бы предпочел, чтобы хранилище было как можно не осведомленным о сущностях.
EDIT:
Я знаю, что это, скорее всего, не является узким местом, я беспокоюсь только о том, что это такая трата, чтобы тратить время на размышления, когда есть немного менее засахаренная альтернатива. И я думаю, что это интересный вопрос:)
Я провел несколько сравнительных тестов, которые оказались весьма интересными (и которые, кажется, подтверждают мои первоначальные подозрения).
Использование инструмента измерения производительности, который я нашел на
http://blogs.msdn.com/b/vancem/archive/2006/09/21/765648.aspx
(который запускает метод тестирования несколько раз и отображает такие показатели, как среднее время и т. д.) Я провел базовый тест, тестирование:
private static T GenFunc<T>() where T : class
{
return dict[typeof(T)] as T;
}
против
private static Object ParamFunc(System.Type type)
{
var d = dict[type];
return d;
}
называется
str = GenFunc<string>();
против
str = (String)ParamFunc(typeof(String));
соответственно. Paramfunc демонстрирует значительное улучшение производительности (выполняется в среднем на 60-70% за время, затрачиваемое на GenFunc), но тест довольно прост, и я могу упустить некоторые вещи. В частности, как приведение типов выполняется в универсальной функции.
Интересно отметить, что при «кэшировании» типа в переменной и его передаче в ParamFunc с использованием typeof () каждый раз достигается небольшая (незначительная) производительность.