2009-08-05 26 views
15

Stavo guardando un codice di esempio e in esso è stato utilizzato un oggetto ListDictionary per memorizzare una piccola quantità di dati (circa 5-10 oggetti o così, ma questo numero potrebbe cambiare nel tempo). L'unico problema che ho con questa classe è che, a differenza di tutto ciò che ho fatto, non è generico. Questo significa, e correggimi se sbaglio qui, che ogni volta ottengo un oggetto fuori da qui o enumerato su di esso che c'è un casting in corso. Esiste un sovraccarico sufficiente nell'oggetto più grande Dictionary<T> per giustificare l'overhead di un ListDictionary non generico?Esiste un'alternativa generica alla classe ListDictionary?

Il codice che utilizzerà questo oggetto verrà enumerato su ogni caricamento di pagina che sto indovinando è perché la classe ListDictionary è stata utilizzata su una delle altre alternative. Questo è anche il motivo per cui mi piacerebbe la maggior parte delle prestazioni di questo elenco di dati.

+0

Hai raggiunto una conclusione e eseguito una misurazione delle prestazioni? Mi dà sempre fastidio usare il dizionario quando ci sarà solo una manciata di elementi nella collezione, ma la comodità di essere lì ha sempre superato il fastidio/rischio associato alla scelta o alla scrittura di qualcos'altro. Non un grosso vantaggio in termini di prestazioni ... a meno che non lo sia. – Rory

risposta

10

Sfortunatamente non esiste un equivalente generico di ListDictionary.

Tuttavia, non dovrebbe essere terribilmente difficile implementarne uno. ListDictionary funziona essenzialmente mantenendo un elenco collegato di coppie chiave/valore e eseguendo il iterazione su di esse per le operazioni di ricerca. È possibile creare un ListDictionary<TKey,TValue> racchiudendo uno LinkedList<T> con alcune espressioni LINQ molto semplici.

Per esempio

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

Immagino che l'utilizzo di LINQ annullerebbe quasi tutti i vantaggi in termini di prestazioni dell'utilizzo di un ListDictionary a meno che il calcolo dei codici hash fosse orribilmente costoso. – Chuu

+0

@Chuu But ListDictionary chiama già Equals su ciascun tasto quando si accede ai valori, quindi perché dovrebbe fornire LINQ Dove si può influire negativamente sulle prestazioni? – sluki

+1

@sluki Allocazione degli oggetti e invocazioni dei delegati rispetto a un singolo metodo che contiene un ciclo for. LINQ è per la leggibilità, non per il codice framework. – jnm2

4

Se i dati che si stanno memorizzando in ListDictionary sono sempre oggetti (classi), piuttosto che tipi di valore, allora sarebbe probabilmente più veloce del dizionario <T>. Se si memorizzano i tipi di valore (structs, int, double, ecc.), Il costo del boxing/unboxing probabilmente compenserà le cose, e invece raccomanderei il dizionario <T>.

Nel complesso, tuttavia, vorrei sottolineare che la differenza di prestazioni tra questi due è probabilmente l'ultimo dei vostri problemi di prestazioni in generale. Piccole cose come questa sono generalmente l'ultima cosa di cui preoccuparsi quando si tratta di ottimizzazione delle prestazioni. Le cose di dimensioni maggiori, come chiamate inter-processo, interazione con database e servizi Web, ecc. Devono essere affrontate prima di non essere mai preoccupate della differenza di prestazioni minore tra ListDictionary e Dizionario <T>.

+0

Concordo pienamente sul fatto che ci sono cose più grandi di cui preoccuparsi in termini di prestazioni. Il motivo per cui ho chiesto questo è che è qualcosa che sto guardando ora e che aggiungo al progetto ora. Quindi, se posso usare un'alternativa migliore alla classe ListDictionary dal momento della partenza, immagino che sia meglio che lasciarlo così com'è. –

1

Un semplice controllo sul MSDN-ListDictionary classe rivelerà

Questa è una semplice implementazione di IDictionary utilizzando un singolarmente concatenata lista. È più piccolo e più veloce di un Hashtable se il numero di elementi è 10 o inferiore. Questo non dovrebbe essere usato se le prestazioni dello sono importanti per i grandi numeri di elementi .

1

Possiamo usare,

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

Per esempio, si consideri il seguente,

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

penso che questo vi aiuterà un po '!

1

Non esiste un equivalente generico di ListDictionary.

Se l'utilizzo di questo piccolo dizionario non è dominato da Add e Remove, si potrebbe considerare SortedList<TKey, TValue>, che, nonostante il nome, implementa IDictionary<TKey, TValue>. A differenza di ListDictionary, che è supportato da un elenco a link singolo, SortedList è supportato da un array di chiavi ordinate e valori di array.

+0

Penso che questa sia la risposta migliore finora. –

Problemi correlati