-
Notifications
You must be signed in to change notification settings - Fork 318
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
Implement Combinations::nth
#914
Implement Combinations::nth
#914
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #914 +/- ##
==========================================
+ Coverage 94.38% 94.45% +0.06%
==========================================
Files 48 48
Lines 6665 6870 +205
==========================================
+ Hits 6291 6489 +198
- Misses 374 381 +7 ☔ View full report in Codecov by Sentry. |
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.
Thanks for this work, I really appreciate it.
I'm gonna skip discussion about using the "combinatorial number system" for now and focus on the current PR.
Have made those two patches, thanks for reviewing :)
|
Do not go via `next()`
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.
I'd prefer if you squashed the commits but I'll merge this anyway as it's nicely done.
I'm curious of the benchmarks, if you want to run it once before the changes and once after.
You can squash them all together at merge time: Here are the benchmarks (comparing to master)
|
also thanks for reviewing these PRs. If there's anything else you think I might be able to work on, let me know :) |
I think the "Squash and merge" option is not selected (and I'm not the owner). I'll merge as is. Thanks for the benchmarks. -65% is nice right? About making #[inline(never)]
fn nth_perf(&mut self, n: usize) ... { ... }
fn nth(&mut self, n: usize) ... {
if n == 0 { ... }
if n >= ARBITRARY_VALUE { return self.nth_perf(n); }
...
} but I wonder if it's worth the trouble. With
Well, I'll surely mention you soon. EDIT: @kinto-b |
@Philippe-Cholet Yep I'll add that helper and have a browse of the other outstanding fold specializations :) Feel free to @ me in anything |
Hi there, this PR addresses #301 in the same way as #329. @Philippe-Cholet I was indeed wrong that this wouldn't give a substantial performance gain
As discussed in the comments of #301, an even more efficient solution which would be performant even in the large n/k regime, would be to use the combinatorial number system. For record keeping sake, here's the function I sketched out before I realised that the itertools uses a 'reversed' lexicographic ordering.
It's possible to use this same idea with the lexicographic ordering used by itertools, but we'd need to know number of elements in the underlying iterator. Suppose we do, and we label this
N
. Then the function above would just need to be modified so thatremainder = checked_binomial(N, self.k()) - n - 1
i = N-1-i
and then reverse the order to ensure that the indices remain strictly increasing.