-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Optimization] avoid copying for intersectInPlace() #419
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
Conversation
96a06b0
to
7848d18
Compare
@dduan Did you measure the performance of this change? Are you seeing any wins? |
@nadavrot to be honest, I only took the hint from the "FIXME" comment and reasoned through the code. I'd love to collect some empirical evidence. Is there any established tools/convention for performance measuring for swift? |
while bucket < native.capacity { | ||
if native.isInitializedEntry(bucket) && | ||
!sequence.contains(native.keyAt(bucket)) { | ||
native.destroyEntryAt(bucket) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation is 2 space.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please leave a FIXME(performance)
comment about the necessity to shrink the storage.
7848d18
to
193e1d6
Compare
var bucket = 0 | ||
while bucket < native.capacity { | ||
if native.isInitializedEntry(bucket) && | ||
!sequence.contains(native.keyAt(bucket)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SequenceType.contains()
consumes the sequence. If our tests didn't catch this, it means this patch needs to add tests that use intersectInPlace()
with MinimalSequence
as the argument.
To fix this issue, you need to use the _preprocessingPass()
method and only query the sequence directly multiple times when it is multi-pass. Otherwise, the sequence needs to be copied to a contiguous array first.
@dduan Thank you for the patch. I support this change, but we need some changes to make sure we keep the code testable and tested. Please take a look at this comment in the file:
Your change needs to move the method to a different category, and expand tests for this method to be more extensive (that is, to test with both native and bridged sets). |
@gribozavr thanks for the comments. I'll make the changes when I get the time. |
@dduan At the moment there is no good way to test the performance of your patch. Can you write a small benchmark program and test the performance before/after? Adding code to the standard library has a cost (in terms of readability and compile time) and we need to have at least on example that shows a performance win. |
@nadavrot will do! |
@nadavrot I ran this program and the speed improvement is around 42% percent (no joke!). Here's the output from my late 2013 MBP with i7:
|
Whoa! |
193e1d6
to
c0bfab5
Compare
By droping down to native storage implementation, we can perform in place intersection without making a copy of the set.
c0bfab5
to
101d698
Compare
f16fc4e
to
5a79983
Compare
5a79983
to
a0ff640
Compare
@gribozavr I think I've addressed most of your comments. Care to take another look? @lattner right back at you! |
@dduan Thank you. The numbers look excellent! |
Closing this one for now. If done right, optimization here would also speed up Thanks @nadavrot @gribozavr |
Added SwiftPM build of Siesta
By droping down to native storage implementation, we can perform in place
intersection without making a copy of the set.
Clears tests in validation-test/stdlib/Set.swift