patterncsharpMinor
Faster Way of Comparing Generic Sets
Viewed 0 times
genericcomparingwayfastersets
Problem
The following extension method is the limiting factor in the performance of an application I am developing, according to Visual Studio 2012 Performance Analysis profiler.
Is there a faster way to compare two collections for set equality?
Is there a faster way to compare two collections for set equality?
public static bool SetEqual(this IEnumerable source, IEnumerable other, IEqualityComparer comparer = null)
{
if (source == null) {
throw new ArgumentNullException("source");
}
if (other == null) {
throw new ArgumentNullException("other");
}
ICollection sourceCollection = source as ICollection ?? source.ToArray();
ICollection otherCollection = other as ICollection ?? other.ToArray();
if (sourceCollection.Count != otherCollection.Count) {
return false;
}
if (sourceCollection.Except(otherCollection, comparer).Any()) {
return false;
}
if (otherCollection.Except(sourceCollection, comparer).Any()) {
return false;
}
return true;
}
Solution
It seems you are iterating the sets a lot with the
Consider iterating the sets at most once:
Source IEnumerable implementation.
Except method and possibly the ToArray.Consider iterating the sets at most once:
public static bool SetEqual(this IEnumerable source, IEnumerable other, IEqualityComparer comparer = null)
{
if (source == null)
throw new ArgumentNullException("source");
if (other == null)
throw new ArgumentNullException("other");
if (source is ICollection &&
other is ICollection &&
((ICollection)source).Count != ((ICollection)other).Count)
return false;
HashSet set;
if (comparer == null)
set = new HashSet(source);
else
set = new HashSet(source, comparer);
return set.SetEquals(other);
}Source IEnumerable implementation.
Code Snippets
public static bool SetEqual<T>(this IEnumerable<T> source, IEnumerable<T> other, IEqualityComparer<T> comparer = null)
{
if (source == null)
throw new ArgumentNullException("source");
if (other == null)
throw new ArgumentNullException("other");
if (source is ICollection &&
other is ICollection &&
((ICollection)source).Count != ((ICollection)other).Count)
return false;
HashSet<T> set;
if (comparer == null)
set = new HashSet<T>(source);
else
set = new HashSet<T>(source, comparer);
return set.SetEquals(other);
}Context
StackExchange Code Review Q#68288, answer score: 5
Revisions (0)
No revisions yet.