README.md

September 27, 2022 · View on GitHub

Arc.Collections

Nuget Build and Test

日本語ドキュメントはこちら

Arc.Collections is a fast C# Collection Library which includes

CollectionDescription
UnorderedList<T>
(equivalent to List<T>)
A list of objects that can be accessed by index.
UnorderedLinkedList<T>
(LinkedList<T>)
A doubly linked list which has Node<T> operation.
OrderedList<T>A list of objects that can be accessed by index and maintained in sorted order. IComparable<T> or IComparer<T> is required.
OrderedKeyValueList<TKey, TValue>
(SortedList<TKey,TValue>)
A list of key-value pairs that can be accessed by index and maintained in sorted order.IComparable<TKey> or IComparer<TKey> is required.
OrderedMap<TKey, TValue>
(SortedDictionary<TKey, TValue>)
A collection of key/value pairs that are sorted on the key (Red-Black Tree). The difference from SortedDictionary<TKey, TValue> is that OrderedMap<TKey, TValue> has Node<T> interface and TKey can be null. IComparable<TKey> or IComparer<TKey> is required.`
OrderedSet
(SortedSet<T>)
A collection of objects that is maintained in sorted order. OrderedSet<T> is a subset of OrderedMap<TKey, TValue> and it's actually OrderedMap<T, int> (TValue int is not used).
OrderedMultiMap<TKey, TValue>A collection of key/value pairs that are sorted on the key. Duplicate keys are allowed in this class.
OrderedMultiSet<T>A collection of objects that is maintained in sorted order. Duplicate keys are allowed in this class.
UnorderedMap<TKey, TValue>
(Dictionary<TKey, TValue>)
A collection of key/value pairs that are stored as a hash table. UnorderedMap<TKey, TValue> is a bit slower than Dictionary<TKey, TValue>, but UnorderedMap<TKey, TValue> has Node index interface and allows null key.
UnorderedSet<T>A subset of UnorderedMap<TKey, TValue> and it's actually UnorderedMap<T, int> (TValue int is not used).
UnorderedMultiMap<TKey, TValue>A collection of key/value pairs that are stored as a hash table. Duplicate keys are allowed in this class.
UnorderedMultiSet<T>A subset of UnorderedMap<TKey, TValue> and it's actually UnorderedMap<T, int> (TValue int is not used).
ObjectPool<T>A fast and thread-safe pool of objects (implemented using ConcurrentQueue<T>).

I know it's reinventing the wheels, but these classes are necessary for implementing CrossLink. And reinventing the wheels is a kind of fun for me :)

Quick Start

Install Arc.Collection using Package Manager Console.

Install-Package Arc.Collection

Sample code. You can use these classes in the same way as generic collection classes.

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> use the same tree structure (Red-Black Tree) as SortedSet<T>. The difference is that OrderedSet<T> has a link to a parent node and is overall faster than SortedSet<T>.

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

The features of the various collections. Please use them well.

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)NoO(1)
UnorderedSet<T>Hash tableNodeO(1)O(1)O(1)NoO(1)
UnorderedMultiMap<K, V>Hash tableNodeO(1)O(1)O(1)NoO(1)
UnorderedMultiSet<T>Hash tableNodeO(1)O(1)O(1)NoO(1)
  • Ordered collections require IComparable<T> or IComparer<T>.
  • Unordered collections (e.g. UnorderedMap<TKey, TValue>) are based on hash tables, which require IEquatable<T>/GetHashCode() or IEqualityComparer<T>.
  • Multi collection allows duplicate keys.
  • OrderedMap uses Red-black trees and is faster than OrderedKeyValueList<TKey, TValue> in most situations. For this reason, I recommend using OrderedMap<TKey, TValue> over OrderedKeyValueList<TKey, TValue> unless index access is absolutely necessary.