Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9309

まさしく車輪の再発明!自作C#コレクションライブラリー Arc.Collection

$
0
0
Arc.Collection Arc.Collectionは各種コレクションを実装した高速なC#ライブラリーです。 本家はGitHub archi-Doc/Arc.Collection にあります。 コレクション 説明 UnorderedList<T> (List<T>と同等) Indexアクセスが可能な、オブジェクトのリスト。 UnorderedLinkedList<T>(LinkedList<T>と同等) 双方向リストで、Node による操作が可能です。 OrderedList<T> ソート済みでIndexアクセスが可能な、オブジェクトのリスト。IComparable<T> または IComparer<T> が必要。 OrderedKeyValueList<TKey, TValue> (SortedList<TKey,TValue>) ソート済みでIndexアクセスが可能な、Key/Valueのリスト。IComparable<TKey> または IComparer<TKey> が必要。 OrderedMap<TKey, TValue>(SortedDictionary<TKey, TValue>) Keyでソート済み(Red-Black Tree)のKey/Value コレクション。 SortedDictionary<TKey, TValue> との違いは、Nodeアクセスが可能なこと、TKeyがnullも可ということです。IComparable<TKey> または IComparer<TKey> が必要。 OrderedSet<T>(SortedSet<T>) ソート済み(Red-Black Tree)のコレクション。 OrderedSet<T> は OrderedMap<TKey, TValue> のサブセットで、実際は OrderedMap<T, int> です(TValue は int で、使用されません)。 OrderedMultiMap<TKey, TValue> Keyでソート済み(Red-Black Tree)のKey/Value コレクション。 重複キーを使用可能です。 OrderedMultiSet<T> ソート済み(Red-Black Tree)のコレクション。重複オブジェクトも可。 UnorderedMap<TKey, TValue>(Dictionary<TKey, TValue>) Hash tableで管理されるKey/Value コレクション。UnorderedMap<TKey, TValue> は Dictionary<TKey, TValue> より少し遅いですが、UnorderedMap<TKey, TValue> はNode index操作が可能で、TKeyがnullも可です。 UnorderedSet<T> UnorderedMap<TKey, TValue> のサブセットで、実際は UnorderedMap<T, int> です(TValue は int で、使用されません)。 UnorderedMultiMap<TKey, TValue> Hash tableで管理されるKey/Value コレクション。重複キーを使用可能です。 UnorderedMultiSet<T> UnorderedMap<TKey, TValue> のサブセットで、実際は UnorderedMap<T, int> です(TValue は int で、使用されません)。 フツーにジェネリックコレクションがあるのに・・・ 車輪の再発明と言うほかありませんが、CrossLink に必要だったため作ってしまいました。実装作業は結構楽しかった。 Quick Start Package Manager Consoleでインストールします。 Install-Package Arc.Collection サンプルコード。フツーのコレクションと同じノリで使用できます。 using Arc.Collection; var array = new int[] { 2, 1, 3, }; var os = new OrderedSet<int>(array); ConsoleWriteIEnumerable("Array:", array); // 2, 1, 3 ConsoleWriteIEnumerable("OrderedSet:", os); // 1, 2, 3 Console.WriteLine("Add 4, 0"); os.Add(4); os.Add(0); ConsoleWriteIEnumerable("OrderedSet:", os); // 0, 1, 2, 3, 4 static void ConsoleWriteIEnumerable<T>(string header, IEnumerable<T> e) { Console.WriteLine(string.Format("{0,-12}", header) + string.Join(", ", e)); } Performance OrderedSet<T> は SortedSet<T> と同様に、データ構造に赤黒木を使用しています。違いは、OrderedSet<T> は内部的に親ノードへのリンクを持つこと、そしてノードアクセスが可能なことです。 SortedSet<T> より高速に動作します。フツーに使っても速いし、Nodeを使ったアクセスは断然速いです。 Reference: System.Collections.Generic.SortedSet<T> Method Length Mean Error StdDev Median Gen 0 Allocated NewAndAdd_SortedSet 100 4,160.11 ns 16.214 ns 22.730 ns 4,157.33 ns 1.0223 4288 B NewAndAdd_OrderedSet 100 3,384.44 ns 8.101 ns 12.126 ns 3,384.49 ns 1.4381 6024 B NewAndAdd2_SortedSet 100 8,709.41 ns 151.310 ns 221.788 ns 8,551.29 ns 1.8463 7776 B NewAndAdd2_OrderedSet 100 8,042.45 ns 53.162 ns 79.570 ns 8,043.79 ns 2.0599 8664 B AddRemove_SortedSet 100 422.21 ns 0.637 ns 0.934 ns 421.94 ns 0.0381 160 B AddRemove_OrderedSet 100 172.03 ns 0.423 ns 0.593 ns 171.93 ns 0.0534 224 B AddRemoveNode_OrderedSet 100 128.04 ns 0.327 ns 0.469 ns 127.89 ns 0.0534 224 B AddRemoveReuse_OrderedSet 100 118.24 ns 0.239 ns 0.335 ns 118.13 ns - - AddRemoveReplace_OrderedSet 100 11.76 ns 0.211 ns 0.289 ns 11.54 ns - - Enumerate_SortedSet 100 1,664.30 ns 17.294 ns 25.349 ns 1,682.97 ns 0.0401 168 B Enumerate_OrderedSet 100 1,218.03 ns 4.344 ns 6.230 ns 1,219.51 ns 0.0114 48 B Collections 各コレクションの特徴です。うまく使い分けてください。 Name Structure Access Add Remove Search Sort Enum. UnorderedList<T> Array Index O(1) O(n) O(n) O(n log n) O(1) UnorderedLinkedList<T> Linked list Node O(1) O(1) O(n) O(n log n) O(1) OrderedList<T> Array Index O(n) O(n) O(log n) Sorted O(1) OrderedKeyValueList<V> Array Index O(n) O(n) O(log n) Sorted O(1) OrderedMap<K, V> RB Tree Node O(log n) O(log n) O(log n) Sorted O(log n) OrderedSet<T> RB Tree Node O(log n) O(log n) O(log n) Sorted O(log n) OrderedMultiMap<K, V> RB Tree Node O(log n) O(log n) O(log n) Sorted O(log n) OrderedMultiSet<T> RB Tree Node O(log n) O(log n) O(log n) Sorted O(log n) UnorderedMap<K, V> Hash table Node O(1) O(1) O(1) - O(1) UnorderedSet<T> Hash table Node O(1) O(1) O(1) - O(1) UnorderedMultiMap<K, V> Hash table Node O(1) O(1) O(1) - O(1) UnorderedMultiSet<T> Hash table Node O(1) O(1) O(1) - O(1) Ordered コレクションはオブジェクトをソートするため、IComparable<T> または IComparer<T> が必要です。 Hash tableを使用するコレクション(UnorderedMap<TKey, TValue>とか)は適切な IEquatable<T>/GetHashCode() または IEqualityComparer<T> が必要です。 Multi がついたコレクションは、重複キーを使用可能です。 OrderedMap<TKey, TValue> は赤黒木(Red-black trees)を使用し、OrderedKeyValueList<TKey, TValue> よりもほとんどのシチュエーションで高速です。絶対にIndexアクセスが必要な場面以外は、OrderedMap<TKey, TValue> の使用をお勧めします。

Viewing all articles
Browse latest Browse all 9309

Trending Articles