mirror of
https://github.com/ICDSystems/ICD.Common.Utils.git
synced 2026-01-11 19:44:55 +00:00
perf: Significant IcdHashSet optimizations
This commit is contained in:
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
### Changed
|
### Changed
|
||||||
- Micro-optimizations in string and XML manipulations
|
- Micro-optimizations in string and XML manipulations
|
||||||
|
- Significant hashset optimizations
|
||||||
|
|
||||||
## [6.0.0] - 2018-10-18
|
## [6.0.0] - 2018-10-18
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -8,12 +8,6 @@ namespace ICD.Common.Utils.Tests.Collections
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public sealed class IcdHashSetTest
|
public sealed class IcdHashSetTest
|
||||||
{
|
{
|
||||||
[Test, UsedImplicitly]
|
|
||||||
public void NullSetTest()
|
|
||||||
{
|
|
||||||
Assert.AreEqual(0, IcdHashSet<int>.NullSet.Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test, UsedImplicitly]
|
[Test, UsedImplicitly]
|
||||||
public void CountTest()
|
public void CountTest()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,12 +16,6 @@ namespace ICD.Common.Utils.Collections
|
|||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a new, empty hashset.
|
|
||||||
/// </summary>
|
|
||||||
[PublicAPI]
|
|
||||||
public static IcdHashSet<T> NullSet { get { return new IcdHashSet<T>(); } }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the number of items contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.
|
/// Gets the number of items contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -98,11 +92,10 @@ namespace ICD.Common.Utils.Collections
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public IcdHashSet<T> Union(IEnumerable<T> set)
|
public IcdHashSet<T> Union(IEnumerable<T> set)
|
||||||
{
|
{
|
||||||
IcdHashSet<T> unionSet = new IcdHashSet<T>(this);
|
|
||||||
|
|
||||||
if (set == null)
|
if (set == null)
|
||||||
return unionSet;
|
throw new ArgumentNullException("set");
|
||||||
|
|
||||||
|
IcdHashSet<T> unionSet = new IcdHashSet<T>(this);
|
||||||
unionSet.AddRange(set);
|
unionSet.AddRange(set);
|
||||||
|
|
||||||
return unionSet;
|
return unionSet;
|
||||||
@@ -116,10 +109,10 @@ namespace ICD.Common.Utils.Collections
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public IcdHashSet<T> Subtract(IEnumerable<T> set)
|
public IcdHashSet<T> Subtract(IEnumerable<T> set)
|
||||||
{
|
{
|
||||||
IcdHashSet<T> subtractSet = new IcdHashSet<T>(this);
|
|
||||||
|
|
||||||
if (set == null)
|
if (set == null)
|
||||||
return subtractSet;
|
throw new ArgumentNullException("set");
|
||||||
|
|
||||||
|
IcdHashSet<T> subtractSet = new IcdHashSet<T>(this);
|
||||||
|
|
||||||
foreach (T item in set)
|
foreach (T item in set)
|
||||||
subtractSet.Remove(item);
|
subtractSet.Remove(item);
|
||||||
@@ -133,17 +126,14 @@ namespace ICD.Common.Utils.Collections
|
|||||||
/// <param name="set"></param>
|
/// <param name="set"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public IcdHashSet<T> Intersection(IcdHashSet<T> set)
|
public IcdHashSet<T> Intersection(IEnumerable<T> set)
|
||||||
{
|
{
|
||||||
IcdHashSet<T> intersectionSet = NullSet;
|
|
||||||
|
|
||||||
if (set == null)
|
if (set == null)
|
||||||
return intersectionSet;
|
throw new ArgumentNullException("set");
|
||||||
|
|
||||||
foreach (T item in this.Where(set.Contains))
|
IcdHashSet<T> intersectionSet = new IcdHashSet<T>();
|
||||||
intersectionSet.Add(item);
|
|
||||||
|
|
||||||
foreach (T item in set.Where(Contains))
|
foreach (T item in set.Where(item => Contains(item)))
|
||||||
intersectionSet.Add(item);
|
intersectionSet.Add(item);
|
||||||
|
|
||||||
return intersectionSet;
|
return intersectionSet;
|
||||||
@@ -155,11 +145,22 @@ namespace ICD.Common.Utils.Collections
|
|||||||
/// <param name="set"></param>
|
/// <param name="set"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public IcdHashSet<T> NonIntersection(IcdHashSet<T> set)
|
public IcdHashSet<T> NonIntersection(IEnumerable<T> set)
|
||||||
{
|
{
|
||||||
IcdHashSet<T> setToCompare = set ?? NullSet;
|
if (set == null)
|
||||||
|
throw new ArgumentNullException("set");
|
||||||
|
|
||||||
return Subtract(set).Union(setToCompare.Subtract(this));
|
IcdHashSet<T> output = new IcdHashSet<T>(this);
|
||||||
|
|
||||||
|
foreach (T item in set)
|
||||||
|
{
|
||||||
|
if (output.Contains(item))
|
||||||
|
output.Remove(item);
|
||||||
|
else
|
||||||
|
output.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -170,9 +171,10 @@ namespace ICD.Common.Utils.Collections
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public bool IsSubsetOf(IcdHashSet<T> set)
|
public bool IsSubsetOf(IcdHashSet<T> set)
|
||||||
{
|
{
|
||||||
IcdHashSet<T> setToCompare = set ?? NullSet;
|
if (set == null)
|
||||||
|
throw new ArgumentNullException("set");
|
||||||
|
|
||||||
return this.All(setToCompare.Contains);
|
return Count <= set.Count && this.All(set.Contains);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -183,9 +185,10 @@ namespace ICD.Common.Utils.Collections
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public bool IsProperSubsetOf(IcdHashSet<T> set)
|
public bool IsProperSubsetOf(IcdHashSet<T> set)
|
||||||
{
|
{
|
||||||
IcdHashSet<T> setToCompare = set ?? NullSet;
|
if (set == null)
|
||||||
|
throw new ArgumentNullException("set");
|
||||||
|
|
||||||
return IsSubsetOf(setToCompare) && !setToCompare.IsSubsetOf(this);
|
return Count < set.Count && IsSubsetOf(set);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -196,9 +199,10 @@ namespace ICD.Common.Utils.Collections
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public bool IsSupersetOf(IcdHashSet<T> set)
|
public bool IsSupersetOf(IcdHashSet<T> set)
|
||||||
{
|
{
|
||||||
IcdHashSet<T> setToCompare = set ?? NullSet;
|
if (set == null)
|
||||||
|
throw new ArgumentNullException("set");
|
||||||
|
|
||||||
return setToCompare.IsSubsetOf(this);
|
return set.IsSubsetOf(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -209,9 +213,10 @@ namespace ICD.Common.Utils.Collections
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public bool IsProperSupersetOf(IcdHashSet<T> set)
|
public bool IsProperSupersetOf(IcdHashSet<T> set)
|
||||||
{
|
{
|
||||||
IcdHashSet<T> setToCompare = set ?? NullSet;
|
if (set == null)
|
||||||
|
throw new ArgumentNullException("set");
|
||||||
|
|
||||||
return IsSupersetOf(setToCompare) && !setToCompare.IsSupersetOf(this);
|
return set.IsProperSubsetOf(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -222,9 +227,10 @@ namespace ICD.Common.Utils.Collections
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public bool SetEquals(IcdHashSet<T> set)
|
public bool SetEquals(IcdHashSet<T> set)
|
||||||
{
|
{
|
||||||
IcdHashSet<T> setToCompare = set ?? NullSet;
|
if (set == null)
|
||||||
|
return Count == 0;
|
||||||
|
|
||||||
return IsSupersetOf(setToCompare) && setToCompare.IsSupersetOf(this);
|
return Count == set.Count && set.All(item => Contains(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -238,9 +244,7 @@ namespace ICD.Common.Utils.Collections
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public bool Add(T item)
|
public bool Add(T item)
|
||||||
{
|
{
|
||||||
// ReSharper disable CompareNonConstrainedGenericWithNull
|
|
||||||
if (item == null)
|
if (item == null)
|
||||||
// ReSharper restore CompareNonConstrainedGenericWithNull
|
|
||||||
throw new ArgumentNullException("item");
|
throw new ArgumentNullException("item");
|
||||||
|
|
||||||
if (m_Dict.ContainsKey(item))
|
if (m_Dict.ContainsKey(item))
|
||||||
@@ -288,6 +292,9 @@ namespace ICD.Common.Utils.Collections
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public bool Contains(T item)
|
public bool Contains(T item)
|
||||||
{
|
{
|
||||||
|
if (item == null)
|
||||||
|
throw new ArgumentNullException("item");
|
||||||
|
|
||||||
return m_Dict.ContainsKey(item);
|
return m_Dict.ContainsKey(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,6 +316,9 @@ namespace ICD.Common.Utils.Collections
|
|||||||
/// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param><exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
|
/// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param><exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
|
||||||
public bool Remove(T item)
|
public bool Remove(T item)
|
||||||
{
|
{
|
||||||
|
if (item == null)
|
||||||
|
throw new ArgumentNullException("item");
|
||||||
|
|
||||||
return m_Dict.Remove(item);
|
return m_Dict.Remove(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user