同様のデータは、多くの場合、コレクションとして格納および操作するときに、より効率的に処理できます。 System.Array クラス、またはSystem.Collections、System.Collections.Generic、System.Collections.Concurrent、およびSystem.Collections.Immutable名前空間のクラスを使用して、個々の要素またはコレクション内の要素の範囲を追加、削除、変更できます。
コレクションには主に 2 種類あります。ジェネリック コレクションと非ジェネリック コレクション。 ジェネリック コレクションは、コンパイル時にタイプ セーフです。 このため、一般的なコレクションでは通常、パフォーマンスが向上します。 ジェネリック コレクションは、構築時に型パラメーターを受け取ります。 コレクションに対して項目を追加または削除するときに、 Object 型との間でキャストする必要はありません。 さらに、ほとんどの汎用コレクションは Windows ストア アプリでサポートされています。 非ジェネリック コレクションは、アイテムを Objectとして格納し、キャストが必要であり、ほとんどの場合、Windows ストア アプリ開発ではサポートされていません。 ただし、古いコードでは非ジェネリック コレクションが表示される場合があります。
.NET Framework 4 以降のバージョンでは、 System.Collections.Concurrent 名前空間のコレクションは、複数のスレッドからコレクション項目にアクセスするための効率的なスレッド セーフな操作を提供します。 System.Collections.Immutable名前空間 (NuGet パッケージ) の不変コレクション クラスは、元のコレクションのコピーに対して操作が実行され、元のコレクションを変更できないため、本質的にスレッド セーフです。
一般的なコレクション機能
すべてのコレクションには、コレクション内の項目を追加、削除、または検索するためのメソッドが用意されています。 さらに、 ICollection インターフェイスまたは ICollection<T> インターフェイスを直接または間接的に実装するすべてのコレクションは、次の機能を共有します。
コレクションを列挙する機能
.NET コレクションは、 System.Collections.IEnumerable または System.Collections.Generic.IEnumerable<T> を実装してコレクションを反復処理できるようにします。 列挙子は、コレクション内の任意の要素への移動可能なポインターと考えることができます。 foreach、in ステートメント、For Each...次のステートメントでは、GetEnumerator メソッドによって公開されている列挙子を使用し、列挙子の操作の複雑さを非表示にします。 さらに、 System.Collections.Generic.IEnumerable<T> を実装するすべてのコレクションは クエリ可能な型 と見なされ、LINQ を使用してクエリを実行できます。 LINQ クエリは、データにアクセスするための一般的なパターンを提供します。 通常、これらは標準の
foreach
ループよりも簡潔で読みやすく、フィルター処理、順序付け、グループ化の機能を提供します。 LINQ クエリを使用すると、パフォーマンスを向上させることもできます。 詳細については、 LINQ to オブジェクト (C#)、 LINQ to Objects (Visual Basic)、 Parallel LINQ (PLINQ)、 LINQ クエリの概要 (C#)、 および基本的なクエリ操作 (Visual Basic)に関するページを参照してください。コレクションの内容を配列にコピーする機能
すべてのコレクションは、
CopyTo
メソッドを使用して配列にコピーできます。 ただし、新しい配列内の要素の順序は、列挙子が返すシーケンスに基づいています。 結果の配列は、常に下限が 0 の 1 次元です。
さらに、多くのコレクション クラスには次の機能が含まれています。
容量とカウントのプロパティ
コレクションの容量は、コレクションに含めることができる要素の数です。 コレクションの数は、コレクションに実際に含まれる要素の数です。 一部のコレクションでは、容量または数、またはその両方が非表示になります。
ほとんどのコレクションは、現在の容量に達すると容量が自動的に拡張されます。 メモリが再割り当てされ、要素が古いコレクションから新しいコレクションにコピーされます。 この設計により、コレクションを使用するために必要なコードが減ります。 ただし、コレクションのパフォーマンスが悪影響を受ける可能性があります。 たとえば、 List<T>の場合、 Count が Capacity未満の場合、項目の追加は O(1) 操作です。 新しい要素に対応するために容量を増やす必要がある場合、項目の追加は O(
n
) 操作になり、n
が Count。 複数の再割り当てによるパフォーマンス低下を回避する最善の方法は、初期容量をコレクションの推定サイズに設定することです。BitArrayは特殊なケースです。容量は長さと同じで、その数と同じです。
一貫性のある下限
コレクションの下限は、最初の要素のインデックスです。 System.Collections名前空間内のすべてのインデックス付きコレクションの下限は 0 です。つまり、インデックスが 0 です。 Arrayには既定では 0 の下限がありますが、Array.CreateInstanceを使用して Array クラスのインスタンスを作成するときに、別の下限を定義できます。
複数のスレッドからのアクセスの同期 (System.Collections クラスのみ)。
System.Collections名前空間の非ジェネリック コレクション型は、一部のスレッド セーフと同期を提供します。通常は、SyncRootおよびIsSynchronized メンバーを介して公開されます。 これらのコレクションは、既定ではスレッド セーフではありません。 コレクションへのスケーラブルで効率的なマルチスレッド アクセスが必要な場合は、 System.Collections.Concurrent 名前空間のいずれかのクラスを使用するか、変更できないコレクションの使用を検討してください。 詳細については、「 コレクションのThread-Safe」を参照してください。
コレクションを選択する
一般に、ジェネリック コレクションを使用する必要があります。 次の表では、一般的なコレクション シナリオと、それらのシナリオに使用できるコレクション クラスについて説明します。 ジェネリック コレクションを初めて使用する場合は、次の表を参考にして、タスクに最適なジェネリック コレクションを選択します。
したいです。。。 | 汎用コレクション オプション | 非ジェネリック コレクション オプション | スレッド セーフまたは不変のコレクション オプション |
---|---|---|---|
キー別にすばやく検索できるように、項目をキーと値のペアとして格納する | Dictionary<TKey,TValue> | Hashtable (キーのハッシュ コードに基づいて編成されたキーと値のペアのコレクション)。 |
ConcurrentDictionary<TKey,TValue> ReadOnlyDictionary<TKey,TValue> ImmutableDictionary<TKey,TValue> |
インデックスでアイテムにアクセスする | List<T> | Array ArrayList |
ImmutableList<T> ImmutableArray |
先入れ先出しアイテムの使用 (FIFO) | Queue<T> | Queue | ConcurrentQueue<T> ImmutableQueue<T> |
Last-In-First-Out (LIFO) のデータを使用する | Stack<T> | Stack | ConcurrentStack<T> ImmutableStack<T> |
アイテムに順番にアクセスする | LinkedList<T> | 推奨事項なし | 推奨事項なし |
アイテムがコレクションに削除または追加されたときに通知を受け取ります。 ( INotifyPropertyChanged と INotifyCollectionChangedを実装します) | ObservableCollection<T> | 推奨事項なし | 推奨事項なし |
並べ替えられたコレクション | SortedList<TKey,TValue> | SortedList | ImmutableSortedDictionary<TKey,TValue> ImmutableSortedSet<T> |
数学関数のセット | HashSet<T> SortedSet<T> |
推奨事項なし | ImmutableHashSet<T> ImmutableSortedSet<T> |
コレクションのアルゴリズムの複雑さ
コレクション クラスを選択する場合は、パフォーマンスの潜在的なトレードオフを考慮する価値があります。 次の表を使用して、さまざまな変更可能なコレクション型がアルゴリズムの複雑さと対応する不変の対応するコレクションとどのように比較されるかを参照します。 多くの場合、不変コレクション型のパフォーマンスは低くなりますが、不変性が提供されます。これは、多くの場合、有効な比較利点です。
変更可能 | 償却 | 最悪のケース | 不変 | 複雑さ |
---|---|---|---|---|
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(ログ n ) |
List<T>.Item[Int32] |
O(1) | O(1) | ImmutableList<T>.Item[Int32] |
O(ログ n ) |
List<T>.Enumerator |
O(n ) |
O(n ) |
ImmutableList<T>.Enumerator |
O(n ) |
HashSet<T>.Add 探索 |
O(1) | O(n ) |
ImmutableHashSet<T>.Add |
O(ログ n ) |
SortedSet<T>.Add |
O(ログ n ) |
O(n ) |
ImmutableSortedSet<T>.Add |
O(ログ n ) |
Dictionary<T>.Add |
O(1) | O(n ) |
ImmutableDictionary<T>.Add |
O(ログ n ) |
Dictionary<T> 探索 |
O(1) | O(1) – または厳密に O(n ) |
ImmutableDictionary<T> 探索 |
O(ログ n ) |
SortedDictionary<T>.Add |
O(ログ n ) |
O(n ログ n ) |
ImmutableSortedDictionary<T>.Add |
O(ログ n ) |
List<T>
は、for
ループまたはforeach
ループを使用して効率的に列挙できます。 ただし、ImmutableList<T>
は、インデクサーの O (ログ n
) 時間が原因で、for
ループ内で不適切なジョブを実行します。
foreach
ループを使用してImmutableList<T>
を列挙すると効率的です。ImmutableList<T>
は、List<T>
が使用する配列の代わりにバイナリ ツリーを使用してデータを格納するためです。 配列にすばやくインデックスを付けることができますが、目的のインデックスを持つノードが見つかるまで、バイナリ ツリーをウォークダウンする必要があります。
さらに、 SortedSet<T>
は、両方ともバイナリ ツリーを使用するため、 ImmutableSortedSet<T>
と同じ複雑さを持ちます。 大きな違いは、 ImmutableSortedSet<T>
は変更できないバイナリ ツリーを使用することです。
ImmutableSortedSet<T>
には変異を許容するSystem.Collections.Immutable.ImmutableSortedSet<T>.Builderクラスも用意されているため、不変性とパフォーマンスの両方を持つことができます。
関連資料
タイトル | 説明 |
---|---|
コレクション クラスの選択 | さまざまなコレクションについて説明し、シナリオに合わせてコレクションを選択するのに役立ちます。 |
一般的に使用されるコレクション型 | System.Array、System.Collections.Generic.List<T>、System.Collections.Generic.Dictionary<TKey,TValue>など、一般的に使用されるジェネリックコレクション型と非ジェネリック コレクション型について説明します。 |
ジェネリック コレクションを使用する場合 | ジェネリック コレクション型の使用について説明します。 |
コレクション内の比較と並べ替え | コレクションでの等価比較と並べ替え比較の使用について説明します。 |
Sorted コレクション型 | 並べ替えられたコレクションのパフォーマンスと特性について説明します。 |
ハッシュテーブルコレクションとディクショナリコレクション型 | ジェネリックおよび非ジェネリック ハッシュ ベースのディクショナリ型の機能について説明します。 |
Thread-Safe コレクション | 複数のスレッドからの安全で効率的な同時アクセスをサポートする System.Collections.Concurrent.BlockingCollection<T> や System.Collections.Concurrent.ConcurrentBag<T> などのコレクション型について説明します。 |
System.Collections.Immutable | 変更できないコレクションを紹介し、コレクション型へのリンクを提供します。 |
リファレンス
.NET