2009-08-05 8 views
15

Ich schaute auf einen Beispielcode und darin verwendeten sie ein ListDictionary Objekt, um eine kleine Menge von Daten zu speichern (etwa 5-10 Objekte oder so, aber diese Zahl könnte sich im Laufe der Zeit ändern). Das einzige Problem, das ich mit dieser Klasse habe, ist, dass es anders als alles, was ich bisher gemacht habe, nicht generisch ist. Das bedeutet, und korrigiere mich, wenn ich hier falsch liege, dass jedes Mal, wenn ich ein Objekt hier herausbekomme oder darüber aufzählen würde, dass ein Casting stattfindet. Gibt es genug Overhead in dem größeren Dictionary<T> Objekt, um den Overhead eines nicht-generischen ListDictionary zu rechtfertigen?Gibt es eine generische Alternative zur ListDictionary-Klasse?

Der Code, der dieses Objekt verwendet, wird bei jedem Laden der Seite aufgelistet, was vermutlich der Grund ist, warum die Klasse ListDictionary über eine der anderen Alternativen verwendet wurde. Das ist auch der Grund, warum ich die meiste Leistung aus dieser Liste von Daten herausholen möchte.

+0

Haben Sie dazu eine Schlussfolgerung gezogen und eine Leistungsmessung durchgeführt? Es stört mich immer, wenn ich ein "Dictionary " verwende, wenn es nur eine Handvoll von Artikeln in der Sammlung gibt, aber die Bequemlichkeit, dass es da ist, hat immer die Mühe/das Risiko in Kauf genommen, etwas anderes zu wählen oder zu schreiben. Leistungstechnisch keine große Sache ... es sei denn, es ist. – Rory

Antwort

10

Leider gibt es kein generisches Äquivalent von ListDictionary.

Es sollte jedoch nicht schrecklich schwierig sein, eins zu implementieren. ListDictionary funktioniert im Wesentlichen, indem es eine verknüpfte Liste von Schlüssel/Wert-Paaren beibehält und für Nachschlagevorgänge über sie iteriert. Sie könnten eine ListDictionary<TKey,TValue> erstellen, indem Sie eine LinkedList<T> mit einigen sehr einfachen LINQ-Ausdrücken umhüllen.

Zum Beispiel

public class LinkedDictionary<TKey,TValue> { 
    private LinkedList<KeyValuePair<TKey,TValue>> _list = new LinkedList<KeyValuePair<TKey,TValue>>(); 
    private IEqualityComparer<TKey> _comp = EqualityComparer<TKey>.Default; 

    public void Add(TKey key, TValue value) { 
    _list.Add(new KeyValuePair<TKey,TValue>(key,value)); 
    } 
    public TValue Get(TKey key) { 
    return _list.Where(x => _comp.Equals(x.Key,key)).First().Value; 
    } 
    ... 
} 
+4

Ich würde mir vorstellen, dass die Verwendung von LINQ fast alle Leistungsvorteile der Verwendung eines ListDictionary zunichte machen würde, es sei denn, die Berechnung von Hash-Codes wäre scheußlich teuer. – Chuu

+0

@Chuu Aber ListDictionary ruft bereits Equals auf jeden Schlüssel beim Zugriff auf Werte, warum sollten LINQs zur Verfügung gestellt werden Wo haben Sie einen negativen Einfluss auf die Leistung? – sluki

+1

@sluki Objektzuordnungen und Delegieren von Aufrufen im Vergleich zu einer einzelnen Methode, die eine for-Schleife enthält. LINQ ist für Lesbarkeit, nicht für Framework-Code. – jnm2

4

Wenn die Daten, die Sie im ListDictionary speichern, immer Objekte (Klassen) statt Werttypen sind, dann wäre es wahrscheinlich schneller als Dictionary <T>. Wenn Sie Werttypen (struct, int, double, usw.) speichern, dann werden die Kosten für das Boxen/Unboxing wahrscheinlich die Dinge ausgleichen, und ich würde stattdessen das Dictionary <T> empfehlen.

Insgesamt möchte ich jedoch darauf hinweisen, dass der Leistungsunterschied zwischen diesen beiden Faktoren wahrscheinlich das geringste Ihrer Leistungsprobleme insgesamt ist. Kleine Dinge wie diese sind in der Regel das letzte, worüber man sich Sorgen machen muss, wenn es um die Leistungsoptimierung geht. Größere Dinge, wie beispielsweise Interprozessaufrufe, Datenbank- und Webservice-Interaktionen usw., sollten zuerst angesprochen werden, bevor man sich jemals Gedanken über den geringfügigen Leistungsunterschied zwischen ListDictionary und Dictionary <T> macht.

+0

Ich stimme voll und ganz zu, dass es in Sachen Leistung größere Sorgen zu geben gibt. Der Grund dafür ist, dass ich es mir jetzt anschaue und es jetzt in das Projekt einfüge. Also, wenn ich eine bessere Alternative zu der ListDictionary-Klasse von Anfang an verwenden kann, dann denke ich, dass es besser ist, als sie zu belassen. –

1

Eine einfache Prüfung auf MSDN-ListDictionary Klasse wird zeigen

Dies ist eine einfache Implementierung von IDictionary eine einfach verkettete Liste. Sie ist kleiner und schneller als eine Hashtable , wenn die Anzahl der Elemente 10 oder weniger ist. Dies sollte nicht verwendet werden, wenn die Leistung für große Elementzahlen wichtig ist.

1

Wir verwenden können,

System.Collections.Generic.Dictionary<Object,Object> dictTemp = new System.Collections.Generic.Dictionary<Object,Object>(); 

Betrachten wir zum Beispiel die folgende,

using System.Collections.Specialized; 

    private ListDictionary g_Attributes = new ListDictionary(); 
    public ListDictionary Attributes 
    { 
     get { return this.g_Attributes; } 
    } 
    public string GetAttribute(string name) 
    { 
     if (HasAttribute(name)) 
      return (string) g_Attributes[name]; 
     else 
      return null; 
    } 
    public bool HasAttribute(string name) 
    { 
     return this.Attributes.Contains(name); 
    } 


    using System.Collection.Generic; 

    private Dictionary<string, object> g_Attributes = new Dictionary<string, object>(); 
    public Dictionary<string, object> Attributes 
    { 
     get { return this.g_Attributes; } 
    } 
    public string GetAttribute(string name) 
    { 
     if (HasAttribute(name)) 
     { 
      return g_Attributes[name].ToString(); 
     } 
     else 
     { 
      return null; 
     } 
    } 
    public bool HasAttribute(string name) 
    { 
    return this.Attributes.ContainsKey(name); 
    } 

Ich denke, das Ihnen ein wenig helfen!

1

Es gibt kein generisches Äquivalent von ListDictionary.

Wenn Ihre Verwendung dieses kleinen Wörterbuch von Add und Remove nicht beherrscht wird, sollten Sie überlegen, SortedList<TKey, TValue>, die trotz ihres Namens IDictionary<TKey, TValue> implementiert. Im Gegensatz zu ListDictionary, das von einer einfach verknüpften Liste unterstützt wird, wird SortedList durch ein Array von sortierten Schlüsseln und Array-Werten unterstützt.

+0

Ich denke, das ist bisher die beste Antwort. –

Verwandte Themen