Repository navigation
Make ExceptWith linear on InsertionOrderSet, OrderedSet and ContiguousSet [patch] - #144
Open
matt-edmondson wants to merge 1 commit into
Open
matt-edmondson wants to merge 1 commit into
matt-edmondson wants to merge 1 commit into
Conversation
…sSet [patch] ExceptWith removed one element at a time, and each removal shifted the list or array tail, so excepting m elements from an n-element set was O(n·m): seconds at 80k elements. It now builds one lookup from `other` with the set's own comparer and compacts the storage in a single pass, as IntersectWith and SymmetricExceptWith already do. Survivors keep their order, and ExceptWith(self) still empties the set. Adds a large-set timing test per type and an ExceptWith benchmark. Fixes #108 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017vfJW6AfToAg6F8bcZwwZ5
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Fixes #108
What was wrong
ExceptWithremoved elements one at a time from list- or array-backed storage, and each removal shifted the tail. Excepting m elements from an n-element set therefore cost O(n·m).IntersectWithandSymmetricExceptWithhad already been changed to compact in one pass, which closed the other rows of the issue's table, butExceptWithwas still per-element on all three types.Change
Each
ExceptWithbuilds one lookup fromother, using the set's own comparer, and then compacts the storage in a single pass:InsertionOrderSet<T>HashSet<T>items.RemoveAll, which also drops each removed item from the uniqueness indexContiguousSet<T>HashSet<T>RemoveWhere, which clears vacated slots and bumpsversiononly when something was removedOrderedSet<T>ToComparerSet, which reusesotherwhen it is anOrderedSetwith the same compareritems.RemoveAllThe surviving elements keep their order.
ExceptWith(self)keeps its earlyClear(). AnExceptWiththat removes nothing still leaves the version unchanged, so it doesn't invalidate a running enumeration.Tests
*_RunsInLinearTimepattern. Each also checks that the survivors come out in order.InsertionOrderSetTests.ExceptWith_LargeSetRemovingEvens_…(200k)ContiguousSetTests.ExceptWith_LargeSetRemovingEvens_…(100k)OrderedSetTests.ExceptWith_LargeEvens_…(800k)OrderedSetneeds the larger size because aList.RemoveAtshift is a fast memmove: at 400k the old code still finished in 3.8 s.Containers.Testsuite: 519 passed, 0 failed.SetExceptWithBenchmarksclass (10k and 80k elements,HashSet<T>as the baseline), which the acceptance criteria asked for. I built it but didn't run it.🤖 Generated with Claude Code
https://claude.ai/code/session_017vfJW6AfToAg6F8bcZwwZ5