2010-12-15 6 views
0

Werfen Sie einen Blick auf diesen Code.List.OfType() Geschwindigkeit, alternative Datenstrukturen

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

Ich habe über 100 von Ladern, und ich brauche viele Züge zu laden, Autos, etc. Ich denke, dass Liste der Lader sehr langsam ist (hat OfType() lineare Komplexität ??), was tun Sie schlagen vor, anstelle der Liste zu verwenden? Dictionary<Type,ILoader> oder Hashtable<Type,ILoader> oder HashSet<ILoader>? Wie schnell wäre es zB hashset.OfType<ILoader<Car>>() zu verwenden, genauso wie Liste oder schneller?

+2

'OfType' ist definiert als eine Erweiterungsmethode für' IEnumerable ', nicht als Instanzmethode auf 'List ' oder einer anderen Sammlung. Solange also die BCL-Designer keine Optimierungen für bestimmte Sammlungen vornehmen, wird die Performance nicht variieren, wenn sie gegen die 'List <>' oder das HashSet <> 'verwendet wird. –

Antwort

6

Erstellen Sie eine Dictionary<Type, ILoader> und bevölkern Sie sie mit den Loadern. Dann können Sie einfach tun:

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

Auf der anderen Seite, wenn Sie haben 100 Einzelteile erhielten durch zu sehen, auch ein linearer Scan ist nicht genau lange dauern würde. Haben Sie tatsächlich eine reale Nutzungssituation bewertet und festgestellt, dass dies Ihr Engpass ist?

+0

Nein, ich habe keine reale Nutzungssituation bewertet ... –

4

Die Erweiterungsmethode Enumerable.OfType läuft in linearer Zeit und ist wahrscheinlich schnell genug für Ihre Zwecke. Optimieren Sie Ihren Code nicht, wenn Sie die Leistung nicht gemessen haben und sicher sind, dass Sie ihn optimieren müssen.

Anstatt sich auf die Leistung zu konzentrieren, sollten Sie zuerst die Eignung Ihres Designs in Betracht ziehen. Ein gutes Design im Allgemeinen muss die Arten des Objekts nicht überprüfen - die Informationen, die Sie benötigen, sollten auf andere Weise verfügbar sein. In diesem Fall möchten Sie beispielsweise fragen, ob jeder Loader ein Objekt laden kann, indem Sie das Objekt an eine -Methode übergeben und true oder zurückgeben. Dies wird Ihr Design flexibler machen.

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

Jetzt können Sie Lader haben, die mehrere Arten von Objekten laden können.

Wenn Sie eine neue Loader jedes Mal, und Sie wollen eine Eins-zu-Eins-Abbildung eine andere Möglichkeit besteht darin, das Objekt auch fragen sich einen geeigneten Lader zu erstellen:

Loader loader = myObject.CreateLoader(); 

Jede Klasse kann CreateLoader unterschiedlich implementieren Damit erhalten Sie einen Loader vom richtigen Typ für Ihr Objekt. Indem Polymorphismus ausgenutzt wird, funktioniert dies ohne jemals ein Objekt fragen zu müssen, um welchen Typ es sich handelt.