Kolekcje i struktury danych
Podobne dane mogą być często obsługiwane wydajniej podczas przechowywania i manipulowania nimi jako kolekcji. Możesz użyć System.Array klasy lub klas w System.Collectionsprzestrzeniach nazw , System.Collections.Generic, System.Collections.Concurrenti System.Collections.Immutable do dodawania, usuwania i modyfikowania pojedynczych elementów lub zakresu elementów w kolekcji.
Istnieją dwa główne typy kolekcji; kolekcje ogólne i kolekcje inne niż ogólne. Kolekcje ogólne są bezpieczne pod typem w czasie kompilacji. Z tego powodu kolekcje ogólne zwykle oferują lepszą wydajność. Kolekcje ogólne akceptują parametr typu podczas ich konstruowania i nie wymagają rzutowania do i z Object typu podczas dodawania lub usuwania elementów z kolekcji. Ponadto większość kolekcji ogólnych jest obsługiwana w aplikacjach ze sklepu Windows Store. Kolekcje inne niż ogólne przechowują elementy jako Object, wymagają rzutu, a większość nie jest obsługiwana w przypadku tworzenia aplikacji ze sklepu Windows Store. Jednak w starszym kodzie mogą być widoczne kolekcje inne niż ogólne.
Począwszy od .NET Framework 4, kolekcje w System.Collections.Concurrent przestrzeni nazw zapewniają wydajne operacje bezpieczne wątkowo na potrzeby uzyskiwania dostępu do elementów kolekcji z wielu wątków. Niezmienne klasy kolekcji w System.Collections.Immutable przestrzeni nazw (pakiet NuGet) są z natury bezpieczne wątkowo, ponieważ operacje są wykonywane na kopii oryginalnej kolekcji i nie można zmodyfikować oryginalnej kolekcji.
Typowe funkcje kolekcji
Wszystkie kolekcje udostępniają metody dodawania, usuwania lub znajdowania elementów w kolekcji. Ponadto wszystkie kolekcje, które bezpośrednio lub pośrednio implementują ICollection interfejs lub ICollection<T> interfejs współużytkują następujące funkcje:
Możliwość wyliczania kolekcji
Kolekcje platformy .NET implementują System.Collections.IEnumerable lub System.Collections.Generic.IEnumerable<T> umożliwiają iterowanie kolekcji. Moduł wyliczający może być uważany za wskaźnik ruchomy do dowolnego elementu w kolekcji. Foreach, w instrukcji i For Each... Następna instrukcja używa modułu wyliczającego uwidocznionego przez metodę GetEnumerator i ukrywa złożoność manipulowania modułem wyliczającym. Ponadto każda kolekcja, która implementuje System.Collections.Generic.IEnumerable<T> , jest uznawana za typ możliwy do wykonywania zapytań i może być odpytywane za pomocą LINQ. Zapytania LINQ zapewniają wspólny wzorzec uzyskiwania dostępu do danych. Są one zazwyczaj bardziej zwięzłe i czytelne niż
foreach
standardowe pętle oraz zapewniają możliwości filtrowania, porządkowania i grupowania. Zapytania LINQ mogą również zwiększyć wydajność. Aby uzyskać więcej informacji, zobacz LINQ to Objects (C#), LINQ to Objects (Visual Basic), Parallel LINQ (PLINQ), Introduction to LINQ Queries (C#), and Basic Query Operations (Visual Basic).Możliwość kopiowania zawartości kolekcji do tablicy
Wszystkie kolekcje można skopiować do tablicy przy użyciu metody CopyTo ; jednak kolejność elementów w nowej tablicy jest oparta na sekwencji, w której moduł wyliczający je zwraca. Wynikowa tablica jest zawsze jednowymiarowa z dolną granicą zera.
Ponadto wiele klas kolekcji zawiera następujące funkcje:
Właściwości pojemności i liczby
Pojemność kolekcji to liczba elementów, które może zawierać. Liczba kolekcji jest liczbą elementów, które faktycznie zawiera. Niektóre kolekcje ukrywają pojemność, liczbę lub obie te kolekcje.
Większość kolekcji automatycznie rozszerza pojemność po osiągnięciu bieżącej pojemności. Pamięć jest ponownie przydzielana, a elementy są kopiowane ze starej kolekcji do nowej. Zmniejsza to kod wymagany do korzystania z kolekcji; jednak wpływ na wydajność kolekcji może mieć negatywny wpływ. Na przykład w przypadku List<T>elementu , jeśli Count wartość jest mniejsza niż Capacity, dodanie elementu jest operacją O(1). Jeśli pojemność musi zostać zwiększona, aby pomieścić nowy element, dodanie elementu staje się operacją O(
n
), gdzien
to Count. Najlepszym sposobem uniknięcia niskiej wydajności spowodowanej przez wiele lokalizacji rzeczywistych jest ustawienie początkowej pojemności na szacowany rozmiar kolekcji.Jest BitArray to szczególny przypadek; jego pojemność jest taka sama jak jego długość, która jest taka sama jak jego liczba.
Spójna dolna granica
Dolna granica kolekcji jest indeksem pierwszego elementu. Wszystkie indeksowane kolekcje w System.Collections przestrzeniach nazw mają dolną granicę zera, co oznacza, że są indeksowane 0. Array domyślnie ma dolną granicę zera, ale można zdefiniować inną dolną granicę podczas tworzenia wystąpienia klasy Array przy użyciu polecenia Array.CreateInstance.
Synchronizacja dostępu z wielu wątków (System.Collections tylko klasy).
Typy kolekcji innych niż ogólne w System.Collections przestrzeni nazw zapewniają pewne bezpieczeństwo wątków z synchronizacją; zazwyczaj są one widoczne za pośrednictwem elementów SyncRoot i IsSynchronized . Te kolekcje nie są domyślnie bezpieczne wątkowo. Jeśli potrzebujesz skalowalnego i wydajnego dostępu wielowątkowego do kolekcji, użyj jednej z klas w System.Collections.Concurrent przestrzeni nazw lub rozważ użycie niezmiennej kolekcji. Aby uzyskać więcej informacji, zobacz Kolekcje wątków Sejf.
Wybieranie kolekcji
Ogólnie rzecz biorąc, należy używać kolekcji ogólnych. W poniższej tabeli opisano niektóre typowe scenariusze kolekcji i klasy kolekcji, których można użyć w tych scenariuszach. Jeśli jesteś nowym użytkownikem kolekcji ogólnych, ta tabela pomoże Ci wybrać kolekcję ogólną, która działa najlepiej dla danego zadania.
Chcę... | Opcje kolekcji ogólnej | Opcje kolekcji nieogólne | Opcje kolekcji bezpieczne wątkowo lub niezmienne |
---|---|---|---|
Przechowywanie elementów jako par klucz/wartość w celu szybkiego wyszukiwania według klucza | Dictionary<TKey,TValue> | Hashtable (Kolekcja par klucz/wartość, które są zorganizowane na podstawie kodu skrótu klucza). |
ConcurrentDictionary<TKey,TValue> ReadOnlyDictionary<TKey,TValue> ImmutableDictionary<TKey,TValue> |
Uzyskiwanie dostępu do elementów według indeksu | List<T> | Array ArrayList |
ImmutableList<T> ImmutableArray |
Używanie elementów pierwszy na pierwszym wyjęcie (FIFO) | Queue<T> | Queue | ConcurrentQueue<T> ImmutableQueue<T> |
Korzystanie z danych Last-In-First-Out (LIFO) | Stack<T> | Stack | ConcurrentStack<T> ImmutableStack<T> |
Sekwencyjnie uzyskiwanie dostępu do elementów | LinkedList<T> | Brak rekomendacji | Brak rekomendacji |
Otrzymywanie powiadomień, gdy elementy są usuwane lub dodawane do kolekcji. (implementuje INotifyPropertyChanged i INotifyCollectionChanged) | ObservableCollection<T> | Brak rekomendacji | Brak rekomendacji |
Posortowana kolekcja | SortedList<TKey,TValue> | SortedList | ImmutableSortedDictionary<TKey,TValue> ImmutableSortedSet<T> |
Zestaw funkcji matematycznych | HashSet<T> SortedSet<T> |
Brak rekomendacji | ImmutableHashSet<T> ImmutableSortedSet<T> |
Algorytmiczna złożoność kolekcji
Podczas wybierania klasy kolekcji warto rozważyć potencjalne kompromisy w wydajności. Skorzystaj z poniższej tabeli, aby dowiedzieć się, jak różne typy kolekcji modyfikowalne porównują się ze złożonością algorytmiczną do odpowiadających im niezmiennych odpowiedników. Często niezmienne typy kolekcji są mniej wydajne, ale zapewniają niezmienność — co często jest prawidłową korzyścią porównawczą.
Modyfikowalny | Amortyzowane | Najgorsza sprawa | Niezmienialny | Złożoność |
---|---|---|---|---|
Stack<T>.Push |
O(1) | O(n ) |
ImmutableStack<T>.Push |
O(1) |
Queue<T>.Enqueue |
O(1) | O(n ) |
ImmutableQueue<T>.Enqueue |
O(1) |
List<T>.Add |
O(1) | O(n ) |
ImmutableList<T>.Add |
O(log n ) |
List<T>.Item[Int32] |
O(1) | O(1) | ImmutableList<T>.Item[Int32] |
O(log n ) |
List<T>.Enumerator |
O(n ) |
O(n ) |
ImmutableList<T>.Enumerator |
O(n ) |
HashSet<T>.Add Wyszukiwania |
O(1) | O(n ) |
ImmutableHashSet<T>.Add |
O(log n ) |
SortedSet<T>.Add |
O(log n ) |
O(n ) |
ImmutableSortedSet<T>.Add |
O(log n ) |
Dictionary<T>.Add |
O(1) | O(n ) |
ImmutableDictionary<T>.Add |
O(log n ) |
Dictionary<T> Wyszukiwania |
O(1) | O(1) – lub ściśle O(n ) |
ImmutableDictionary<T> Wyszukiwania |
O(log n ) |
SortedDictionary<T>.Add |
O(log n ) |
O(n dziennik n ) |
ImmutableSortedDictionary<T>.Add |
O(log n ) |
Element List<T>
może być skutecznie wyliczany przy użyciu for
pętli lub foreach
pętli. Jednak ImmutableList<T>
, wykonuje słabe zadanie wewnątrz for
pętli, ze względu na czas O(log n
) dla indeksatora. Wyliczanie ImmutableList<T>
przy użyciu foreach
pętli jest wydajne, ponieważ ImmutableList<T>
używa drzewa binarnego do przechowywania danych zamiast prostej tablicy, takiej jak List<T>
użycie. Tablica może być bardzo szybko indeksowana, natomiast drzewo binarne musi przechodzić w dół do momentu znalezienia węzła z żądanym indeksem.
SortedSet<T>
Ponadto ma taką samą złożoność jak ImmutableSortedSet<T>
. To dlatego, że obaj używają drzew binarnych. Znacząca różnica polega oczywiście na tym, że ImmutableSortedSet<T>
używa niezmiennego drzewa binarnego. Ponieważ ImmutableSortedSet<T>
oferuje również klasę System.Collections.Immutable.ImmutableSortedSet<T>.Builder , która umożliwia mutację, może mieć zarówno niezmienność, jak i wydajność.
Tematy pokrewne
Tytuł | Opis |
---|---|
Wybieranie klasy kolekcji | Opisuje różne kolekcje i pomaga wybrać jedną z nich dla danego scenariusza. |
Często używane typy kolekcji | Opisuje powszechnie używane typy kolekcji ogólnych i niegenerycznych, takich jak System.Array, System.Collections.Generic.List<T>i System.Collections.Generic.Dictionary<TKey,TValue>. |
Kiedy należy używać kolekcji ogólnych | Omówienie użycia typów kolekcji ogólnych. |
Porównania i sortowanie w kolekcjach | Omówienie użycia porównań równości i porównań sortowania w kolekcjach. |
Sortowane typy kolekcji | Opisuje posortowaną wydajność i charakterystykę kolekcji |
Typy kolekcji tablic wartości funkcji mieszającej i słowników | Opisuje funkcje ogólnych i niegenerycznych typów słowników opartych na skrótach. |
Kolekcje Sejf wątków | Opisuje typy kolekcji, takie jak System.Collections.Concurrent.BlockingCollection<T> i System.Collections.Concurrent.ConcurrentBag<T> , które obsługują bezpieczny i wydajny współbieżny dostęp z wielu wątków. |
System.Collections.Niezmienny | Wprowadza niezmienne kolekcje i udostępnia linki do typów kolekcji. |
Tematy pomocy
System.Array System.Collections System.Collections.Concurrent System.Collections.Generic System.Collections.Specialized System.Linq System.Collections.Immutable