Widzę, że proponowane odpowiedzi koncentrują się na wydajności. Poniższy artykuł nie zawiera żadnych nowych informacji dotyczących wydajności, ale wyjaśnia podstawowe mechanizmy. Należy również zauważyć, że nie koncentruje się na trzech Collection
typach wymienionych w pytaniu, ale dotyczy wszystkich typów w System.Collections.Generic
przestrzeni nazw.
http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choosing-the-right-collection-class.aspx
Ekstrakty:
Słownik <>
Słownik jest prawdopodobnie najczęściej używaną asocjacyjną klasą kontenera. Słownik jest najszybszą klasą do asocjacyjnego wyszukiwania / wstawiania / usuwania, ponieważ używa tablicy skrótów pod okładkami . Ponieważ klucze są hashowane, typ klucza powinien poprawnie implementować GetHashCode () i Equals () lub należy podać zewnętrzny IEqualityComparer do słownika podczas konstrukcji. Czas wstawiania / usuwania / wyszukiwania elementów w słowniku jest amortyzowany jako stały czas - O (1) - co oznacza, że bez względu na to, jak duży jest słownik, czas potrzebny na znalezienie czegoś pozostaje względnie stały. Jest to bardzo pożądane w przypadku szybkiego wyszukiwania. Jedynym minusem jest to, że słownik, z natury korzystający z tablicy skrótów, jest nieuporządkowany, więcnie możesz łatwo przeglądać po kolei elementów w Słowniku .
SortedDictionary <>
SortedDictionary jest podobny do Dictionary w użyciu, ale bardzo różni się implementacją. SortedDictionary wykorzystuje binarne drzewo pod kołdrą aby utrzymać pozycje w kolejności od klucza . W konsekwencji sortowania typ używany dla klucza musi poprawnie implementować IComparable, aby klucze mogły być poprawnie sortowane. Posortowany słownik wykorzystuje trochę czasu wyszukiwania na możliwość utrzymania pozycji w porządku, dlatego czasy wstawiania / usuwania / wyszukiwania w posortowanym słowniku są logarytmiczne - O (log n). Ogólnie rzecz biorąc, w przypadku czasu logarytmicznego można podwoić rozmiar zbioru i wystarczy wykonać tylko jedno dodatkowe porównanie, aby znaleźć element. Użyj SortedDictionary, jeśli chcesz szybko wyszukiwać, ale chcesz również mieć możliwość utrzymywania kolekcji w kolejności według klucza.
SortedList <>
SortedList to inna posortowana asocjacyjna klasa kontenera w kontenerach ogólnych. Po raz kolejny SortedList, podobnie jak SortedDictionary, używa klucza do sortowania par klucz-wartość . Jednak w przeciwieństwie do SortedDictionary elementy w SortedList są przechowywane jako posortowana tablica elementów. Oznacza to, że wstawienia i usunięcia są liniowe - O (n) - ponieważ usunięcie lub dodanie pozycji może wiązać się z przesunięciem wszystkich pozycji w górę lub w dół listy. Jednak czas wyszukiwania wynosi O (log n), ponieważ SortedList może użyć wyszukiwania binarnego, aby znaleźć dowolny element na liście według jego klucza. Więc dlaczego miałbyś kiedykolwiek chcieć to zrobić? Cóż, odpowiedź jest taka, że jeśli zamierzasz załadować SortedList z góry, wstawianie będzie wolniejsze, ale ponieważ indeksowanie tablicy jest szybsze niż śledzenie łączy obiektów, wyszukiwania są nieznacznie szybsze niż SortedDictionary. Ponownie użyłbym tego w sytuacjach, w których chcesz szybko wyszukiwać i chcesz zachować porządek w kolekcji według klucza, a wstawienia i usunięcia są rzadkie.
Wstępne podsumowanie podstawowych procedur
Opinie są mile widziane, ponieważ jestem pewien, że nie wszystko ułożyło się dobrze.
- Wszystkie tablice mają określony rozmiar
n
.
- Niesortowana tablica = .Add / .Remove to O (1), ale .Item (i) to O (n).
- Posortowana tablica = .Add / .Remove to O (n), ale .Item (i) to O (log n).
Słownik
Pamięć
KeyArray(n) -> non-sorted array<pointer>
ItemArray(n) -> non-sorted array<pointer>
HashArray(n) -> sorted array<hashvalue>
Dodaj
- Dodaj
HashArray(n) = Key.GetHash
nr O (1)
- Dodaj
KeyArray(n) = PointerToKey
nr O (1)
- Dodaj
ItemArray(n) = PointerToItem
nr O (1)
Usunąć
For i = 0 to n
, znajdź i
gdzie HashArray(i) = Key.GetHash
# O (log n) (posortowana tablica)
- Usuń
HashArray(i)
# O (n) (posortowana tablica)
- Usuń
KeyArray(i)
# O (1)
- Usuń
ItemArray(i)
# O (1)
Zdobądź przedmiot
For i = 0 to n
, znajdź i
gdzie HashArray(i) = Key.GetHash
# O (log n) (posortowana tablica)
- Powrót
ItemArray(i)
Loop Through
For i = 0 to n
, powrót ItemArray(i)
SortedDictionary
Pamięć
KeyArray(n) = non-sorted array<pointer>
ItemArray(n) = non-sorted array<pointer>
OrderArray(n) = sorted array<pointer>
Dodaj
- Dodaj
KeyArray(n) = PointerToKey
nr O (1)
- Dodaj
ItemArray(n) = PointerToItem
nr O (1)
For i = 0 to n
, znajdź i
gdzie KeyArray(i-1) < Key < KeyArray(i)
(używając ICompare
) # O (n)
- Dodaj
OrderArray(i) = n
# O (n) (posortowana tablica)
Usunąć
For i = 0 to n
znajdź, i
gdzie KeyArray(i).GetHash = Key.GetHash
# O (n)
- Usuń
KeyArray(SortArray(i))
# O (n)
- Usuń
ItemArray(SortArray(i))
# O (n)
- Usuń
OrderArray(i)
# O (n) (posortowana tablica)
Zdobądź przedmiot
For i = 0 to n
znajdź, i
gdzie KeyArray(i).GetHash = Key.GetHash
# O (n)
- Powrót
ItemArray(i)
Loop Through
For i = 0 to n
, powrót ItemArray(OrderArray(i))
SortedList
Pamięć
KeyArray(n) = sorted array<pointer>
ItemArray(n) = sorted array<pointer>
Dodaj
For i = 0 to n
, znajdź i
gdzie KeyArray(i-1) < Key < KeyArray(i)
(używając ICompare
) # O (log n)
- Dodaj
KeyArray(i) = PointerToKey
# O (n)
- Dodaj
ItemArray(i) = PointerToItem
# O (n)
Usunąć
For i = 0 to n
znajdź, i
gdzie KeyArray(i).GetHash = Key.GetHash
# O (log n)
- Usuń
KeyArray(i)
# O (n)
- Usuń
ItemArray(i)
# O (n)
Zdobądź przedmiot
For i = 0 to n
znajdź, i
gdzie KeyArray(i).GetHash = Key.GetHash
# O (log n)
- Powrót
ItemArray(i)
Loop Through
For i = 0 to n
, powrót ItemArray(i)