diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenSetInternalBase.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenSetInternalBase.cs index 4afe1f7503e757..c6dd2612f7b404 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenSetInternalBase.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenSetInternalBase.cs @@ -130,6 +130,20 @@ private protected override bool OverlapsCore(IEnumerable other) { Debug.Assert(_thisSet.Count != 0, "EmptyFrozenSet should have been used."); + return other switch + { + // Fast path for Overlaps when other is HashSet and same equality comparer + HashSet hs when _thisSet.Comparer.Equals(hs.Comparer) => OverlapsCompatibleSetImpl(hs), + + // Fast path for Overlaps when other is FrozenSet and same equality comparer + FrozenSet fs when _thisSet.Comparer.Equals(fs.Comparer) => OverlapsCompatibleSetImpl(fs), + + _ => OverlapsEnumerableImpl(other) + }; + } + + private bool OverlapsEnumerableImpl(IEnumerable other) + { foreach (T element in other) { if (_thisSet.FindItemIndex(element) >= 0) @@ -141,6 +155,46 @@ private protected override bool OverlapsCore(IEnumerable other) return false; } + private bool OverlapsCompatibleSetImpl(HashSet other) + { + return other.Count > Count + ? SmallerSetOverlapsLargerCompatibleSetImpl(this, other) + : SmallerSetOverlapsLargerCompatibleSetImpl(other, this); + } + + private bool OverlapsCompatibleSetImpl(FrozenSet other) + { + return other.Count > Count + ? SmallerSetOverlapsLargerCompatibleSetImpl(this, other) + : SmallerSetOverlapsLargerCompatibleSetImpl(other, this); + } + + private static bool SmallerSetOverlapsLargerCompatibleSetImpl(FrozenSet smaller, ISet larger) + { + foreach (T element in smaller) + { + if (larger.Contains(element)) + { + return true; + } + } + + return false; + } + + private static bool SmallerSetOverlapsLargerCompatibleSetImpl(HashSet smaller, FrozenSetInternalBase larger) + { + foreach (T element in smaller) + { + if (larger._thisSet.FindItemIndex(element) >= 0) + { + return true; + } + } + + return false; + } + /// private protected override bool SetEqualsCore(IEnumerable other) {