Skip to content

[stdlib][performance] skip copying old values during removeAll(keepCapacity: true) #616

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

Merged
merged 1 commit into from
Dec 18, 2015

Conversation

dduan
Copy link
Contributor

@dduan dduan commented Dec 17, 2015

(This is a re-submission of #477 with clearer patch and description.)

For .removeAll(keepCapacity: true) on a non-uniquely referenced Dictionary or Set, the existing code implements COW by calling ensureUniqueNativeStorage(), which actually copies the content of its storage. Only then the elements get deleted one by one.

A FIXME(performance) comment stated this wastefulness (benchmark result posted in #477 agrees). A better solution is directly replace the native storage with equal capacity.

A note on Set: As @dabrahams pointed out, aSet.removeAll() is the equivalent of aSet.intersectInPlace([]). Ideally, intersectInPlace(), being the more general case, should be the target for optimization. In successfully doing so, the equivalence in math can be directly realized in code.

In that light, this patch can be treated as solely an optimization for Dictionary. The speedup for Set is a side-effect (courtesy of GYP and architect of this file).

Tests in both swift/validation-test/stdlib/Set.swift and ./lit swift/validation-test/stdlib/Dictionary.swift are passing.

@dduan dduan changed the title [stdlib] skip copying old values during removeAll(keepCapacity: true) [stdlib][performance] skip copying old values during removeAll(keepCapacity: true) Dec 17, 2015
@dduan dduan force-pushed the removeAll_speedup branch from c48b898 to 2111f7b Compare December 17, 2015 06:27
As noted in FIXME(performance), calling `.removeAll(keepCapacity: true)` on a
containter of type Dictionay or Set causes a copy of its storage being made.
Only then, it would proceed to delete each element.

This patch makes these hashed collections skip the wasteful copying step.
@dduan dduan force-pushed the removeAll_speedup branch from 2111f7b to b177c69 Compare December 17, 2015 06:28
@nadavrot
Copy link
Contributor

@dduan Can you please write a simple benchmark that verifies that things go faster now?

@dduan
Copy link
Contributor Author

dduan commented Dec 17, 2015

@nadavrot Here

unoptimized:
23.2448832392693

optimized:
0.0532280802726746

@nadavrot
Copy link
Contributor

@dduan Excellent!!

@dduan
Copy link
Contributor Author

dduan commented Dec 18, 2015

Your thoughts, @gribozavr ?

@lattner
Copy link
Contributor

lattner commented Dec 18, 2015

Only a 438x improvement? I don't know, perhaps we should pass on this. :-)

+1 from me, but @gribozavr or @dabrahams need to approve it.

@gribozavr
Copy link
Contributor

@dduan Looks great, thank you!

gribozavr added a commit that referenced this pull request Dec 18, 2015
[stdlib][performance] skip copying old values during removeAll(keepCapacity: true)
@gribozavr gribozavr merged commit f436764 into swiftlang:master Dec 18, 2015
@dduan dduan deleted the removeAll_speedup branch December 23, 2019 21:49
freak4pc pushed a commit to freak4pc/swift that referenced this pull request Sep 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants