Скорость List.OfType (), альтернативные структуры данных - PullRequest
0 голосов
/ 16 декабря 2010

Посмотрите на этот код.

interface ILoader
{
}

interface ILoader<T>: ILoader
{
    T Load();
}

class CarLoader: ILoader<Car>
{
    ...
}

class TrainLoader: ILoader<Train>
{
    ...
}

class Container
{
     List<ILoader> loaders = new ILoader[] { new CarLoader(), new TrainLoader()};

     public T Load<T>()
     {
         // Finding right loader
         var loader = loaders.OfType<ILoader<Car>>.FirstOrDefault();
         return loader.Load();
     }
}

У меня около 100 погрузчиков, и мне нужно загрузить много поездов, вагонов и т. Д. Я думаю, что список загрузчиков очень медленный(имеет OfType() линейную сложность ??), что вы предлагаете использовать вместо списка?Dictionary<Type,ILoader> или Hashtable<Type,ILoader> или HashSet<ILoader>?Как быстро, например, использовать hashset.OfType<ILoader<Car>>(), как список или быстрее?

Ответы [ 2 ]

6 голосов
/ 16 декабря 2010

Постройте Dictionary<Type, ILoader> и заполните его загрузчиками.Тогда вы можете просто сделать:

ILoader<T> loader = (ILoader<T>) loaderDictionary[typeof(T)];

С другой стороны, если вам нужно просмотреть только 100 элементов, даже линейное сканирование не займет много времени.Вы действительно оценили реальную ситуацию использования и обнаружили, что это ваше узкое место?

4 голосов
/ 16 декабря 2010

Метод расширения Enumerable.OfType работает за линейное время и, вероятно, достаточно быстр для ваших целей.Не оптимизируйте микро-код до тех пор, пока вы не измерили производительность и не уверены, что вам нужно оптимизировать его.

Вместо того, чтобы концентрироваться на производительности, вы должны в первую очередь подумать о пригодности вашего дизайна.Хороший дизайн в целом не должен проверять типы объекта - необходимая информация должна быть доступна другими способами.В этом случае, например, вы можете спросить, способен ли каждый загрузчик загрузить объект, передав этот объект методу CanLoad и вернув true или false.Это сделает ваш дизайн более гибким.

Loader loader = loaders.First(x => x.CanLoad(myObject));

Теперь у вас могут быть загрузчики, которые могут загружать объекты нескольких типов.

Если вы каждый раз хотите новый загрузчик и вам нужен одно-сопоставление to-one другой вариант - также попросить сам объект создать подходящий загрузчик:

Loader loader = myObject.CreateLoader();

Каждый класс может реализовывать CreateLoader по-своему, так что вы получаете загрузчик правильного типа для вашего объекта.Используя преимущества полиморфизма, это работает без необходимости спрашивать объект, какой это тип.

...