Ich kann sehen, dass sich die vorgeschlagenen Antworten auf die Leistung konzentrieren. Der folgende Artikel enthält keine neuen Informationen zur Leistung, erläutert jedoch die zugrunde liegenden Mechanismen. Beachten Sie auch, dass es sich nicht auf die drei Collection
in der Frage genannten Typen konzentriert, sondern alle Typen des System.Collections.Generic
Namespace anspricht .
http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choosing-the-right-collection-class.aspx
Auszüge:
Wörterbuch <>
Das Wörterbuch ist wahrscheinlich die am häufigsten verwendete assoziative Containerklasse. Das Wörterbuch ist die schnellste Klasse für assoziative Suchvorgänge / Einfügungen / Löschungen, da es eine Hash-Tabelle unter dem Deckblatt verwendet . Da die Schlüssel gehasht sind, sollte der Schlüsseltyp GetHashCode () und Equals () korrekt implementieren, oder Sie sollten dem Wörterbuch bei der Erstellung einen externen IEqualityComparer bereitstellen. Die Einfüge- / Lösch- / Nachschlagezeit von Elementen im Wörterbuch ist die amortisierte konstante Zeit - O (1) - was bedeutet, dass die Zeit, die benötigt wird, um etwas zu finden, relativ konstant bleibt, egal wie groß das Wörterbuch wird. Dies ist für Hochgeschwindigkeitssuchen sehr wünschenswert. Der einzige Nachteil ist, dass das Wörterbuch aufgrund der Verwendung einer Hash-Tabelle ungeordnet istSie können die Elemente in einem Wörterbuch nicht einfach der Reihe nach durchlaufen .
SortedDictionary <>
Das SortedDictionary ähnelt dem verwendeten Dictionary, unterscheidet sich jedoch in der Implementierung erheblich. Das SortedDictionary verwendet einen Binärbaum unter der Abdeckung, um die Elemente in der Reihenfolge nach dem Schlüssel zu verwalten . Infolge der Sortierung muss der für den Schlüssel verwendete Typ IComparable korrekt implementieren, damit die Schlüssel korrekt sortiert werden können. Das sortierte Wörterbuch tauscht ein wenig Nachschlagzeit gegen die Fähigkeit, die Elemente in der richtigen Reihenfolge zu halten. Daher sind die Einfüge- / Lösch- / Nachschlagezeiten in einem sortierten Wörterbuch logarithmisch - O (log n). Im Allgemeinen können Sie mit logarithmischer Zeit die Größe der Sammlung verdoppeln, und es muss nur ein zusätzlicher Vergleich durchgeführt werden, um den Artikel zu finden. Verwenden Sie das SortedDictionary, wenn Sie schnell nachschlagen möchten, aber auch die Sammlung nach Schlüssel sortieren möchten.
SortedList <>
Die SortedList ist die andere sortierte assoziative Containerklasse in den generischen Containern. Wieder verwendet SortedList wie SortedDictionary einen Schlüssel, um Schlüssel-Wert-Paare zu sortieren . Im Gegensatz zu SortedDictionary werden Elemente in einer SortedList jedoch als sortiertes Array von Elementen gespeichert. Dies bedeutet, dass Einfügungen und Löschungen linear sind - O (n) -, da beim Löschen oder Hinzufügen eines Elements möglicherweise alle Elemente in der Liste nach oben oder unten verschoben werden. Die Suchzeit ist jedoch O (log n), da die SortedList eine binäre Suche verwenden kann, um jedes Element in der Liste anhand seines Schlüssels zu finden. Warum sollten Sie das jemals tun wollen? Die Antwort lautet: Wenn Sie die SortedList im Voraus laden, werden die Einfügungen langsamer. Da die Array-Indizierung jedoch schneller ist als das Folgen von Objektverknüpfungen, sind Suchvorgänge geringfügig schneller als bei einem SortedDictionary. Ich würde dies wieder in Situationen verwenden, in denen Sie schnell nachschlagen und die Sammlung in der Reihenfolge des Schlüssels verwalten möchten und in der Einfügungen und Löschungen selten sind.
Vorläufige Zusammenfassung der zugrunde liegenden Verfahren
Feedback ist sehr willkommen, da ich sicher nicht alles richtig gemacht habe.
- Alle Arrays sind von Größe
n
.
- Nicht sortiertes Array = .Add / .Remove ist O (1), aber .Item (i) ist O (n).
- Sortiertes Array = .Add / .Remove ist O (n), aber .Item (i) ist O (log n).
Wörterbuch
Erinnerung
KeyArray(n) -> non-sorted array<pointer>
ItemArray(n) -> non-sorted array<pointer>
HashArray(n) -> sorted array<hashvalue>
Hinzufügen
- Addiere
HashArray(n) = Key.GetHash
# O (1)
- Addiere
KeyArray(n) = PointerToKey
# O (1)
- Addiere
ItemArray(n) = PointerToItem
# O (1)
Entfernen
For i = 0 to n
, finde i
wo HashArray(i) = Key.GetHash
# O (log n) (sortiertes Array)
- Entfernen Sie
HashArray(i)
# O (n) (sortiertes Array)
- Entfernen Sie
KeyArray(i)
# O (1)
- Entfernen Sie
ItemArray(i)
# O (1)
Gegenstand erhalten
For i = 0 to n
, finde i
wo HashArray(i) = Key.GetHash
# O (log n) (sortiertes Array)
- Rückkehr
ItemArray(i)
Durchschleifen
For i = 0 to n
, Rückkehr ItemArray(i)
SortedDictionary
Erinnerung
KeyArray(n) = non-sorted array<pointer>
ItemArray(n) = non-sorted array<pointer>
OrderArray(n) = sorted array<pointer>
Hinzufügen
- Addiere
KeyArray(n) = PointerToKey
# O (1)
- Addiere
ItemArray(n) = PointerToItem
# O (1)
For i = 0 to n
, finde i
wo KeyArray(i-1) < Key < KeyArray(i)
(mit ICompare
) # O (n)
- Addiere
OrderArray(i) = n
# O (n) (sortiertes Array)
Entfernen
For i = 0 to n
, finde i
wo KeyArray(i).GetHash = Key.GetHash
# O (n)
- Entferne
KeyArray(SortArray(i))
# O (n)
- Entferne
ItemArray(SortArray(i))
# O (n)
- Entfernen Sie
OrderArray(i)
# O (n) (sortiertes Array)
Gegenstand erhalten
For i = 0 to n
, finde i
wo KeyArray(i).GetHash = Key.GetHash
# O (n)
- Rückkehr
ItemArray(i)
Durchschleifen
For i = 0 to n
, Rückkehr ItemArray(OrderArray(i))
SortedList
Erinnerung
KeyArray(n) = sorted array<pointer>
ItemArray(n) = sorted array<pointer>
Hinzufügen
For i = 0 to n
, finde i
wo KeyArray(i-1) < Key < KeyArray(i)
(mit ICompare
) # O (log n)
- Addiere
KeyArray(i) = PointerToKey
# O (n)
- Addiere
ItemArray(i) = PointerToItem
# O (n)
Entfernen
For i = 0 to n
, finde i
woKeyArray(i).GetHash = Key.GetHash
# O (log n)
- Entferne
KeyArray(i)
# O (n)
- Entferne
ItemArray(i)
# O (n)
Gegenstand erhalten
For i = 0 to n
, finde i
wo KeyArray(i).GetHash = Key.GetHash
# O (log n)
- Rückkehr
ItemArray(i)
Durchschleifen
For i = 0 to n
, Rückkehr ItemArray(i)