LoginSignup
1
1

More than 3 years have passed since last update.

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

Posted at

Arc.Collection

Nuget Build and Test

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> の使用をお勧めします。
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1