-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
improve worst-case performance of BTreeSet intersection v1 #58577
Conversation
r? @KodrAus (rust_highfive has picked a reviewer for you, use r? to override) |
Thanks @ssomers! Would you be able to put together some benchmarks so we could get an idea of what the impact is for intersecting variously sized sets? |
I'm not sure how to contrast the various implementations in the same build. But I could first PR a benchmark in src\liballoc\benches\btree using the existing implementation, then merge this here and anyone looking closely enough would see times improve. |
Rough numbers on my system:
As you see, intersection of very asymmetric set (10 versus 10,000 elements) is mostly up, except if the set containing only numbers lower than any in the other set (neg = negative ints vs. pos=positive ints) is also a small set (i.e. the algorithm merely iterates over that small set and finishes). The latter could be improved upon by limiting both sets to the range started with the smallest element of the other set. The whole algorithm could work like that: instead of iterating, find the next element >= the other set's lowest unseen value. But then sometimes/often the binary search towards the next element would be worse than iterating, in particular for the staggered test case. |
📌 Commit 4fd0cc1 has been approved by |
🌲 The tree is currently closed for pull requests below priority 99, this pull request will be tested once the tree is reopened |
…drAus improve worst-case performance of BTreeSet intersection Major performance boost when comparing tiny and huge sets. Probably with controversial changes and I sure have questions: - Names and places of functions and types - How many comments to write where - Why does rustc tell me to `ref mut` and `ref` matches on the iterator, while the book says ref is old school. - (Why) do I have to write out the clone like that (`#[derive(Clone)]` doesn't work) - Am I allowed to use `#[derive(Debug)]` there at all? - I'd like to test function `are_proportionate_for_intersection` in test_intersection (or another test case next to it) itself, but I think the private function is inaccessible there. liballoc has other test cases not in the tests directory. PS I don't list these questions to start a discussion here, just to inspire reviewers and to remember myself.
…marks, r=KodrAus introduce benchmarks of BTreeSet.intersection 16 tests combining 4 kinds of contents with different sizes exposing edge cases. The ones with asymmetric sizes are addressed by rust-lang#58577. The pos_vs_neg cases seems (are were meant to be) the same as the neg_vs_pos case (same thing, reverse order) but reality shows a surprsing 25% difference.
With the last commit added on top, rough numbers on my system are almost all down:
As to taking this further with "instead of iterating, find the next element >= the other set's lowest unseen value", no cigar: it slows down intersect_random_10k 2.5 times, and (absolute worst case) intersect_staggered_10k 14x. |
More tweaks:
No more ideas at the moment so that's going to be the last batch, unless there are remarks. |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
Your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem. Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
…nction because its outcome is reported by the benchmarks
…red output; add a few more
improve worst-case performance of BTreeSet intersection Alternative to [pull request #58577](#58577): back out of attempts to optimize using ranges, more elegant code (I think). The stable public type Intersection changes from struct to enum. If that matters, then perhaps changing the fields like in the other proposal also mattered.
Major performance boost when comparing tiny and huge sets. Probably with controversial changes and I sure have questions:
ref mut
andref
matches on the iterator, while the book says ref is old school: fixed in code, should take it up to compiler people.#[derive(Clone)]
doesn't work): see improve worst-case performance of BTreeSet intersection v3 #59186 (comment)_#[derive(Debug)]
there at all? Yes, but the actual Debug.fmt implementation should supersede it.are_proportionate_for_intersection
in test_intersection (or another test case next to it) itself, but I think the private function is inaccessible there. liballoc has other test cases not in the tests directory.PS I don't list these questions to start a discussion here, just to inspire reviewers and to remember myself.