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 Collection
tipi menzionati nella domanda, ma si rivolge a tutti i tipi dello System.Collections.Generic
spazio dei nomi.
http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choosing-the-right-collection-class.aspx
Estratti:
Dizionario <>
Il Dictionary è probabilmente la classe contenitore associativa più utilizzata. Il Dictionary è la classe più veloce per ricerche / inserimenti / eliminazioni associative perché utilizza una tabella hash sotto le coperte . Poiché le chiavi sono sottoposte ad hashing, il tipo di chiave dovrebbe implementare correttamente GetHashCode () ed Equals () in modo appropriato oppure fornire un IEqualityComparer esterno al dizionario durante la costruzione. Il tempo di inserimento / cancellazione / ricerca degli elementi nel dizionario è tempo costante ammortizzato - O (1) - il che significa che non importa quanto sia grande il dizionario, il tempo necessario per trovare qualcosa rimane relativamente costante. Ciò è altamente desiderabile per le ricerche ad alta velocità. L'unico svantaggio è che il dizionario, per natura dell'utilizzo di una tabella hash, non è ordinato, quindinon è possibile attraversare facilmente gli elementi in un dizionario in ordine .
SortedDictionary <>
SortedDictionary è simile al Dictionary nell'uso ma molto diverso nell'implementazione. Il SortedDictionary utilizza un albero binario sotto le coperte per mantenere gli elementi in ordine dal tasto . 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, puoi raddoppiare le dimensioni della collezione e devi solo eseguire un confronto extra per trovare l'oggetto. 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 di contenitori associativi ordinati 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 di elementi ordinati. Ciò significa che gli inserimenti e le eliminazioni sono lineari - O (n) - perché 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) perché SortedList può utilizzare una ricerca binaria per trovare qualsiasi elemento nell'elenco tramite la sua chiave. Allora perché mai dovresti volerlo fare? Bene, la risposta è che se hai intenzione di caricare il SortedList in anticipo, gli inserimenti saranno più lenti, ma poiché l'indicizzazione dell'array è più veloce dei seguenti collegamenti a oggetti, le ricerche sono leggermente più veloci di un SortedDictionary. Ancora una volta lo userei in situazioni in cui desideri ricerche veloci e vuoi mantenere la raccolta in ordine per chiave e dove gli inserimenti e le cancellazioni sono rari.
Riepilogo provvisorio delle procedure sottostanti
Il feedback è molto gradito perché sono sicuro di non aver fatto tutto bene.
- Tutti gli array sono di dimensioni
n
.
- Array non ordinato = .Add / .Remove è O (1), ma .Item (i) è O (n).
- Matrice ordinata = .Add / .Remove è O (n), ma .Item (i) è O (log n).
Dizionario
Memoria
KeyArray(n) -> non-sorted array<pointer>
ItemArray(n) -> non-sorted array<pointer>
HashArray(n) -> sorted array<hashvalue>
Inserisci
- Aggiungi
HashArray(n) = Key.GetHash
# O (1)
- Aggiungi
KeyArray(n) = PointerToKey
# O (1)
- Aggiungi
ItemArray(n) = PointerToItem
# O (1)
Rimuovere
For i = 0 to n
, trova i
dove HashArray(i) = Key.GetHash
# O (log n) (array ordinato)
- Rimuovi
HashArray(i)
# O (n) (array ordinato)
- Rimuovi
KeyArray(i)
# O (1)
- Rimuovi
ItemArray(i)
# O (1)
Ottieni oggetto
For i = 0 to n
, trova i
dove HashArray(i) = Key.GetHash
# O (log n) (array ordinato)
- Ritorno
ItemArray(i)
Loop Through
For i = 0 to n
, ritorno ItemArray(i)
SortedDictionary
Memoria
KeyArray(n) = non-sorted array<pointer>
ItemArray(n) = non-sorted array<pointer>
OrderArray(n) = sorted array<pointer>
Inserisci
- Aggiungi
KeyArray(n) = PointerToKey
# O (1)
- Aggiungi
ItemArray(n) = PointerToItem
# O (1)
For i = 0 to n
, trova i
dove KeyArray(i-1) < Key < KeyArray(i)
(usando ICompare
) # O (n)
- Aggiungi
OrderArray(i) = n
# O (n) (array ordinato)
Rimuovere
For i = 0 to n
, trova i
dove KeyArray(i).GetHash = Key.GetHash
# O (n)
- Rimuovi
KeyArray(SortArray(i))
# O (n)
- Rimuovi
ItemArray(SortArray(i))
# O (n)
- Rimuovi
OrderArray(i)
# O (n) (array ordinato)
Ottieni oggetto
For i = 0 to n
, trova i
dove KeyArray(i).GetHash = Key.GetHash
# O (n)
- Ritorno
ItemArray(i)
Loop Through
For i = 0 to n
, ritorno ItemArray(OrderArray(i))
SortedList
Memoria
KeyArray(n) = sorted array<pointer>
ItemArray(n) = sorted array<pointer>
Inserisci
For i = 0 to n
, trova i
dove KeyArray(i-1) < Key < KeyArray(i)
(usando ICompare
) # O (log n)
- Aggiungi
KeyArray(i) = PointerToKey
# O (n)
- Aggiungi
ItemArray(i) = PointerToItem
# O (n)
Rimuovere
For i = 0 to n
, trova i
dove KeyArray(i).GetHash = Key.GetHash
# O (log n)
- Rimuovi
KeyArray(i)
# O (n)
- Rimuovi
ItemArray(i)
# O (n)
Ottieni oggetto
For i = 0 to n
, trova i
dove KeyArray(i).GetHash = Key.GetHash
# O (log n)
- Ritorno
ItemArray(i)
Loop Through
For i = 0 to n
, ritorno ItemArray(i)