-
Notifications
You must be signed in to change notification settings - Fork 10.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Set and Dictionary should have remove(where:)
.
#78364
Comments
Agreed, with the name |
Hi, is this still open? |
@ maintainers if possible can you assign it to me so that i will raise an PR for this. |
@krishpranav Please note that this addition requires a Swift evolution proposal — hence the corresponding label. |
so should i need to create a new proposal like that? |
You are welcome to! Make sure to follow the process document that is linked there. |
pitch: (swiftlang/swift-evolution#2647) |
@dabrahams I've been thinking about the polarity of this operation. Also some vague spitballing about how we might implement a set partition efficiently... (@lorentey, @natecook1000?) |
I find I also think it's possibly a good idea to have readable duplicates of functional term-of-art functions. The latter need to be there so people can find them if they think in those terms, but I'm not sure they're helpful to anyone else. Since you can't reorder the items in a set, it's not clear to me what you might mean by “a set partition.” |
I'm asking, somewhat handwavily, if we can partition the set into two sets that leave the element storage as-is, updating one hash table in-place, and creating a new hash table for the "removed" set. We could provide an overload that doesn't bother to create the removed set for your pure in-place removal operation, but also give people a way to get the removed elements efficiently without making them iterate through them. |
We can definitely provide an operation that splits a set/dictionary into two parts based on some provided predicate, and in a way that's better than manually looping through items. We do not have tombstones, so we cannot generally avoid rehashing items, even with in-place removals (because we need to compress collision chains). But there is still plenty of opportunity for optimization -- for example, for bulk operations it's been particularly helpful to precalculate predicate results into a temporary bitmap in an up front pass before selecting a strategy. (The bitmap gives us a precise picture of the size of the results, so we can avoid repeated resizings of newly allocated hash table results, and we can heuristically switch between in-place removals and building a new table based on the number of items that remain in place. Bulk in-place removals are often considerably slower than copying the remaining elements directly into a brand new, well-sized hash table. In-place removals can also leave the table wildly oversized, which is sometimes unexpected/wasteful.) |
Since your set representation is resilient, it might be possible to leave the underlying storage alone and simply refer to it from something that stores a bitset to tell you which elements are actually present in that partition. Lookup operations would need to check the bitmap to make sure that element is actually in the partition, and the collection index movement operations would change to skip elements not indicated in the bitmap. You could even share a single bitmap allocation, where the bits tell you which partition each element is in. |
The standard (The generic lookup paths needed to remain fully specializable, to avoid shipping a dramatic performance regression in Swift 5.) |
IMO (sadly) if you're going with |
Motivation
It's not possible to implement this operation efficiently from outside the library. You either iterate a snapshot and end up silently copying the collection, or you have to collect the items to be removed in a separate collection and then
.subtract
that.Proposed solution
Add
remove(where:)
toSet
andDictionary
.Alternatives considered
No response
Additional information
No response
The text was updated successfully, but these errors were encountered: