README.jp.md

April 24, 2021 · View on GitHub

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>

MethodLengthMeanErrorStdDevMedianGen 0Allocated
NewAndAdd_SortedSet1004,160.11 ns16.214 ns22.730 ns4,157.33 ns1.02234288 B
NewAndAdd_OrderedSet1003,384.44 ns8.101 ns12.126 ns3,384.49 ns1.43816024 B
NewAndAdd2_SortedSet1008,709.41 ns151.310 ns221.788 ns8,551.29 ns1.84637776 B
NewAndAdd2_OrderedSet1008,042.45 ns53.162 ns79.570 ns8,043.79 ns2.05998664 B
AddRemove_SortedSet100422.21 ns0.637 ns0.934 ns421.94 ns0.0381160 B
AddRemove_OrderedSet100172.03 ns0.423 ns0.593 ns171.93 ns0.0534224 B
AddRemoveNode_OrderedSet100128.04 ns0.327 ns0.469 ns127.89 ns0.0534224 B
AddRemoveReuse_OrderedSet100118.24 ns0.239 ns0.335 ns118.13 ns--
AddRemoveReplace_OrderedSet10011.76 ns0.211 ns0.289 ns11.54 ns--
Enumerate_SortedSet1001,664.30 ns17.294 ns25.349 ns1,682.97 ns0.0401168 B
Enumerate_OrderedSet1001,218.03 ns4.344 ns6.230 ns1,219.51 ns0.011448 B

Collections

各コレクションの特徴です。うまく使い分けてください。

NameStructureAccessAddRemoveSearchSortEnum.
UnorderedList<T>ArrayIndexO(1)O(n)O(n)O(n log n)O(1)
UnorderedLinkedList<T>Linked listNodeO(1)O(1)O(n)O(n log n)O(1)
OrderedList<T>ArrayIndexO(n)O(n)O(log n)SortedO(1)
OrderedKeyValueList<V>ArrayIndexO(n)O(n)O(log n)SortedO(1)
OrderedMap<K, V>RB TreeNodeO(log n)O(log n)O(log n)SortedO(log n)
OrderedSet<T>RB TreeNodeO(log n)O(log n)O(log n)SortedO(log n)
OrderedMultiMap<K, V>RB TreeNodeO(log n)O(log n)O(log n)SortedO(log n)
OrderedMultiSet<T>RB TreeNodeO(log n)O(log n)O(log n)SortedO(log n)
UnorderedMap<K, V>Hash tableNodeO(1)O(1)O(1)-O(1)
UnorderedSet<T>Hash tableNodeO(1)O(1)O(1)-O(1)
UnorderedMultiMap<K, V>Hash tableNodeO(1)O(1)O(1)-O(1)
UnorderedMultiSet<T>Hash tableNodeO(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> の使用をお勧めします。