简体   繁体   English

List.OfType()速度,替代数据结构

[英]List.OfType() speed, alternative data structures

Take a look at this code. 看一下这段代码。

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();
     }
}

I've got about 100 of loaders and I need to load a lot of Trains, Cars, etc. I think that List of loaders is very slow (has OfType() linear complexity??), what do you suggest to use instead of list? 我有大约100个装载机,我需要装载很多火车,汽车等。我认为装载机清单非常慢(具有OfType()线性复杂度?),您建议使用什么代替清单? Dictionary<Type,ILoader> or Hashtable<Type,ILoader> or HashSet<ILoader> ? Dictionary<Type,ILoader>Hashtable<Type,ILoader>HashSet<ILoader>吗? How fast would be for example to use hashset.OfType<ILoader<Car>>() , same as list or faster? 例如,使用hashset.OfType<ILoader<Car>>()与列表相同还是更快?

Build a Dictionary<Type, ILoader> and populate it with the loaders. 构建一个Dictionary<Type, ILoader>并用加载器填充它。 Then you can just do: 然后,您可以执行以下操作:

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

On the other hand, if you've only got 100 items to look through, even a linear scan isn't exactly going to take long. 另一方面,如果您只需要查看100个项目,那么即使线性扫描也不会花费很长时间。 Have you actually benchmarked a real usage situation and found this to be your bottleneck? 您是否实际对实际使用情况进行了基准测试,并发现这是您的瓶颈?

The Enumerable.OfType extension method does run in linear time and it is probably fast enough for your purposes. Enumerable.OfType扩展方法确实在线性时间内运行,它可能足够快地满足您的目的。 Don't micro-optimizate your code unless you have measured the performance and are sure that you need to optimize it. 除非已测量性能并确定需要对其进行优化,否则请不要对代码进行微优化。

Rather than concentrating on the performance you should first consider the suitability of your design. 与其关注性能,不如先考虑设计的适用性。 A good design in general does not need to inspect the types of the object - the information you need should be available in other ways. 好的设计通常不需要检查对象的类型-您需要的信息应该以其他方式提供。 In this case for example you might want to ask if each loader is capable of loading an object by passing that object to a CanLoad method and returning true or false . 例如,在这种情况下,您可能想询问每个加载器是否能够通过将对象传递给CanLoad方法并返回truefalse来加载该对象。 This will make your design more flexible. 这将使您的设计更加灵活。

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

Now you can have loaders that can load multiple types of objects. 现在,您可以拥有可以加载多种类型对象的加载器。

If you want a new Loader each time and you want a one-to-one mapping another option is to also ask the object itself to create a suitable loader: 如果您每次都想要一个新的加载器,并且想要一对一的映射,那么另一个选择是也要求对象本身创建一个合适的加载器:

Loader loader = myObject.CreateLoader();

Each class can implement CreateLoader differently so that you get a Loader of the correct type for your object. 每个类可以以不同的方式实现CreateLoader以便为您的对象获得正确类型的Loader。 By taking advantage of polymorphism this works without ever needing to ask an object what type it is. 通过利用多态性,该方法无需询问对象是什么类型就可以工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM