SortedList < > ;, SortedDictionary < > e dizionario < >
-
07-07-2019 - |
Domanda
Trovo che SortedList < TKey, TValue >
SortedDictionary < TKey, TValue >
e Dictionary < TKey, TValue >
implementano le stesse interfacce .
- Quando dovremmo optare per
SortedList
eSortedDictionary
suDizionario
? - Qual è la differenza tra
SortedList
eSortedDictionary
in termini di applicazione?
Soluzione
-
Quando si ripetono gli elementi in uno dei due, gli elementi verranno ordinati. Non così con
Dictionary<T,V>
. -
MSDN risolve la differenza tra
SortedList < ; T, V >
eSortedDictionary < T, V >
:
La classe generica SortedDictionary (TKey, TValue) è una ricerca binaria albero con recupero O (log n), dove n è il numero di elementi in il dizionario. A questo proposito, è simile a SortedList (TKey, TValue) classe generica. Le due classi hanno modelli di oggetti simili e entrambi hanno il recupero O (log n). Dove si trovano le due classi diverse utilizzo della memoria e velocità di inserimento e rimozione:
SortedList (TKey, TValue) utilizza meno memoria di SortedDictionary (TKey, TValue).
SortedDictionary (TKey, TValue) ha inserimento e rimozione più rapidi operazioni per dati non ordinati: O (log n) rispetto a O (n) per SortedList (TKey, TValue).
Se l'elenco viene popolato tutto in una volta dai dati ordinati, SortedList (TKey, TValue) è più veloce di SortedDictionary (TKey, TValue).
Altri suggerimenti
Vorrei citare la differenza tra i dizionari.
L'immagine qui sopra mostra che Dictionary < K, V >
è uguale o più veloce in ogni caso rispetto all'analogo Sorted
, ma se è richiesto l'ordine degli elementi, ad es. per stamparli, Ordinati
ne viene scelto uno
Riassumendo i risultati di un Test delle prestazioni - SortedList vs. SortedDictionary vs. Dizionario vs. Hashtable , i risultati dalla migliore alla peggiore per diversi scenari:
Utilizzo della memoria:
SortedList<T,T>
Hashtable
SortedDictionary<T,T>
Dictionary<T,T>
inserimenti:
Dictionary<T,T>
Hashtable
SortedDictionary<T,T>
SortedList<T,T>
Operazioni di ricerca:
Hashtable
Dictionary<T,T>
SortedList<T,T>
SortedDictionary<T,T>
Operazioni foreach loop
SortedList<T,T>
Dictionary<T,T>
Hashtable
SortedDictionary<T,T>
-
Quando si desidera che la raccolta venga ordinata per chiave quando si esegue l'iterazione su di essa. Se non hai bisogno di ordinare i tuoi dati, stai meglio con solo un dizionario, avrà prestazioni migliori.
-
SortedList e SortedDictionary fanno praticamente la stessa cosa, ma sono implementati in modo diverso, quindi hanno diversi punti di forza e di debolezza spiegato qui .
Vedo che le risposte proposte si concentrano sulle prestazioni. L'articolo fornito di seguito non fornisce nulla di nuovo riguardo alle prestazioni, ma spiega i meccanismi sottostanti. Si noti inoltre che non si concentra sui tre tipi Collection
citati nella domanda, ma riguarda tutti i tipi dello spazio dei nomi System.Collections.Generic
.
Estratti:
Dictionnary < >
Il dizionario è probabilmente la classe contenitore associativa più utilizzata. Il dizionario è la classe più veloce per ricerche associative / inserti / eliminazioni perché utilizza una tabella hash sotto le copertine . Poiché le chiavi sono sottoposte a hash, il tipo di chiave dovrebbe implementare correttamente GetHashCode () e Equals () in modo appropriato o dovresti fornire un IEqualityComparer esterno al dizionario durante la costruzione. Il tempo di inserimento / eliminazione / ricerca degli elementi nel dizionario è tempo costante ammortizzato - O (1) - il che significa non importa quanto sia grande il dizionario, il tempo impiegato per trovare qualcosa rimane relativamente costante. Questo è altamente desiderabile per le ricerche ad alta velocità. L'unico aspetto negativo è che il dizionario, per natura dell'uso di una tabella hash, non è ordinato, quindi non è possibile attraversare facilmente gli elementi in un dizionario in ordine .
SortedDictionary < >
SortedDictionary è simile al Dizionario in uso ma molto diverso nell'implementazione. SortedDictionary utilizza un albero binario sotto le copertine per mantenere gli elementi in ordine tramite la chiave . Come conseguenza dell'ordinamento, il tipo utilizzato per la chiave deve implementare correttamente IComparable in modo che le chiavi possano essere ordinate correttamente. Il dizionario ordinato scambia un po 'di tempo di ricerca per la capacità di mantenere gli elementi in ordine, quindi i tempi di inserimento / cancellazione / ricerca in un dizionario ordinato sono logaritmici - O (log n). In generale, con il tempo logaritmico, è possibile raddoppiare le dimensioni della raccolta e per trovare l'oggetto è sufficiente eseguire un ulteriore confronto. Usa SortedDictionary quando vuoi ricerche veloci ma vuoi anche essere in grado di mantenere la raccolta in ordine dalla chiave.
SortedList < >
SortedList è l'altra classe contenitore associativa ordinata nei contenitori generici. Ancora una volta SortedList, come SortedDictionary, utilizza una chiave per ordinare le coppie chiave-valore . A differenza di SortedDictionary, tuttavia, gli elementi in un SortedList vengono archiviati come array ordinati di elementi . Ciò significa che gli inserimenti e le eliminazioni sono lineari - O (n) - poiché l'eliminazione o l'aggiunta di un elemento può comportare lo spostamento di tutti gli elementi in alto o in basso nell'elenco. Il tempo di ricerca, tuttavia, è O (log n) poiché SortedList può utilizzare una ricerca binaria per trovare qualsiasi elemento nell'elenco mediante la sua chiave. Quindi perché mai vorresti farlo? Bene, la risposta è che se caricherai la SortedList in anticipo, gli inserimenti saranno più lenti, ma poiché l'indicizzazione dell'array è più veloce rispetto ai seguenti collegamenti agli oggetti, le ricerche sono leggermente più veloci di un SortedDictionary. Ancora una volta lo userei in situazioni in cui desideri ricerche rapide e desideri mantenere la raccolta in ordine tramite la chiave e in cui inserimenti ed eliminazioni sono rari.
Riepilogo provvisorio delle procedure sottostanti
Il feedback è molto gradito in quanto sono sicuro di non aver fatto tutto bene.
- Tutti gli array hanno dimensioni
n
. - Matrice non ordinata = .Add / .Remove è O (1), ma .Item (i) è O (n).
- Matrice ordinata = .Add / .Remove è O (n), ma .Item (i) è O (1).
Dictionnary
Memory
KeyArray (n) - > array non ordinato < pointer >
ItemArray (n) - > array non ordinato < pointer >
HashArray (n) - > array ordinato < hashvalue >
Aggiungi
- Aggiungi
HashArray (n) = Key.GetHash
# O (1) - Aggiungi
KeyArray (n) = PointerToKey
# O (1) - Aggiungi
ItemArray (n) = PointerToItem
# O (1)
Rimuovi
-
Per i = da 0 a n
, trovai
doveHashArray (i) = Key.GetHash
# O (registro n) (ordinato array) - Rimuovi
HashArray (i)
# O (n) (matrice ordinata) - Rimuovi
KeyArray (i)
# O (1) - Rimuovi
ItemArray (i)
# O (1)
Ottieni oggetto
-
Per i = da 0 a n
, trovai
doveHashArray (i) = Key.GetHash
# O (registro n) (ordinato array) - Restituisce
ItemArray(i)
Passa attraverso
-
Per i = da 0 a n
, restituisceItemArray(i)
SortedDictionary
Memory
KeyArray (n) = array non ordinato < pointer >
ItemArray (n) = array non ordinato < pointer >
OrderArray (n) = array ordinato < pointer >
Aggiungi
- Aggiungi
KeyArray (n) = PointerToKey
# O (1) - Aggiungi
ItemArray (n) = PointerToItem
# O (1) -
Per i = da 0 a n
, trovai
doveKeyArray (i-1) < Chiave < KeyArray (i)
(utilizzandoICompare
) # O (n) - Aggiungi
OrderArray (i) = n
# O (n) (array ordinato)
Rimuovi
-
Per i = 0 a n
, trovai
doveKeyArray (i) .GetHash = Key.GetHash
# O (n) - Rimuovi
KeyArray (SortArray (i))
# O (1) - Rimuovi
ItemArray (SortArray (i))
# O (1) - Rimuovi
OrderArray (i)
# O (n) (array ordinato)
Ottieni oggetto
-
Per i = 0 a n
, trovai
doveKeyArray (i) .GetHash = Key.GetHash
# O (n) - Restituisce
ItemArray(i)
Passa attraverso
-
Per i = da 0 a n
, restituisceItemArray(OrderArray(i))
SortedList
Memory
KeyArray (n) = array ordinato < pointer >
ItemArray (n) = array ordinato < pointer >
Aggiungi
-
Per i = da 0 a n
, trovai
doveKeyArray (i-1) < Chiave < KeyArray (i)
(utilizzandoICompare
) # O (log n) - Aggiungi
KeyArray (i) = PointerToKey
# O (n) - Aggiungi
ItemArray (i) = PointerToItem
# O (n)
Rimuovi
-
Per i = 0 a n
, trovai
doveKeyArray (i) .GetHash = Key.GetHash
# O (registro n) - Rimuovi
KeyArray (i)
# O (n) - Rimuovi
ItemArray (i)
# O (n)
Ottieni oggetto
-
Per i = 0 a n
, trovai
doveKeyArray (i) .GetHash = Key.GetHash
# O (registro n) - Restituisce
ItemArray(i)
Passa attraverso
-
Per i = da 0 a n
, restituisceItemArray(i)
Cercando di assegnare un punteggio di rendimento a ciascun caso presentato da @Lev, ho usato i seguenti valori:
- O (1) = 3
- O (registro n) = 2
- O (n) = 1
- O (1) o O (n) = 2
- O (log n) o O (n) = 1.5
I risultati sono (più alto = migliore):
Dictionary: 12.0
SortedDictionary: 9.0
SortedList: 6.5
Ovviamente, ogni caso d'uso darà più peso a determinate operazioni.