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..f36ce9cf0eb0ea 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,19 @@ private protected override bool OverlapsCore(IEnumerable other) { Debug.Assert(_thisSet.Count != 0, "EmptyFrozenSet should have been used."); + // Fast path for Overlaps when other is IReadOnlySet with fast lookup and same equality comparer + if (other is IReadOnlySet otherAsSet && ComparersAreCompatible(otherAsSet)) + { + return otherAsSet.Count > Count + ? SmallerFrozenSetOverlapsLargerCompatibleReadOnlySetImpl(this, otherAsSet) + : LargerFrozenSetOverlapsSmallerCompatibleReadOnlySetImpl(otherAsSet, this); + } + + return OverlapsEnumerableImpl(other); + } + + private bool OverlapsEnumerableImpl(IEnumerable other) + { foreach (T element in other) { if (_thisSet.FindItemIndex(element) >= 0) @@ -141,6 +154,32 @@ private protected override bool OverlapsCore(IEnumerable other) return false; } + private static bool SmallerFrozenSetOverlapsLargerCompatibleReadOnlySetImpl(FrozenSet smaller, IReadOnlySet larger) + { + foreach (T element in smaller) + { + if (larger.Contains(element)) + { + return true; + } + } + + return false; + } + + private static bool LargerFrozenSetOverlapsSmallerCompatibleReadOnlySetImpl(IReadOnlySet smaller, FrozenSet larger) + { + foreach (T element in smaller) + { + if (larger.Contains(element)) + { + return true; + } + } + + return false; + } + /// private protected override bool SetEqualsCore(IEnumerable other) {