Skip to content

Speed up binomial #39891

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 3 commits into from
Apr 18, 2025
Merged

Speed up binomial #39891

merged 3 commits into from
Apr 18, 2025

Conversation

user202729
Copy link
Contributor

@user202729 user202729 commented Apr 5, 2025

As first observed in #39379, when n and k are small sage integers, binomial(n, k) are much slower than n.binomial(k).

This pull request fixes it. Now %timeit binomial(20, 10) is only twice slower than %timeit 20.binomial(10) — previously it was 30 times slower.

There's also a minor patch where some code is skipped when all arguments are instances of Element. It is certainly a more common case for the input to be Element than otherwise, so we optimize for it.

Another minor patch involves storing imported modules as C global variables instead of re-import every time.

I think using not-overriding _method_arguments as an indicator of "don't call the method"
(then silently catch TypeError and throw it away) is rather bad design,
but this is not in scope here.

📝 Checklist

  • The title is concise and informative.
  • The description explains in detail what this PR is about.
  • I have linked a relevant issue or discussion.
  • I have created tests covering the changes.
  • I have updated the documentation and checked the documentation preview.

Copy link

github-actions bot commented Apr 5, 2025

Documentation preview for this PR (built with commit 3cf1002; changes) is ready! 🎉
This preview will update shortly after each push to this PR.

Copy link
Collaborator

@tscrim tscrim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is quite an impressive speedup for such a minor change. LGTM.

vbraun pushed a commit to vbraun/sage that referenced this pull request Apr 10, 2025
sagemathgh-39891: Speed up binomial
    
As first observed in sagemath#39379, when
`n` and `k` are small sage integers, `binomial(n, k)` are much slower
than `n.binomial(k)`.

This pull request fixes it. Now `%timeit binomial(20, 10)` is only twice
slower than `%timeit 20.binomial(10)` — previously it was **30** times
slower.

There's also a minor patch where some code is skipped when all arguments
are instances of `Element`. It is certainly a more common case for the
input to be `Element` than otherwise, so we optimize for it.

Another minor patch involves storing imported modules as C global
variables instead of re-import every time.

I think using not-overriding `_method_arguments` as an indicator of
"don't call the method"
(then silently catch `TypeError` and throw it away) is rather bad
design,
but this is not in scope here.

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->

- [x] The title is concise and informative.
- [x] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [x] I have created tests covering the changes.
- [ ] I have updated the documentation and checked the documentation
preview.
    
URL: sagemath#39891
Reported by: user202729
Reviewer(s): Travis Scrimshaw
vbraun pushed a commit to vbraun/sage that referenced this pull request Apr 13, 2025
sagemathgh-39891: Speed up binomial
    
As first observed in sagemath#39379, when
`n` and `k` are small sage integers, `binomial(n, k)` are much slower
than `n.binomial(k)`.

This pull request fixes it. Now `%timeit binomial(20, 10)` is only twice
slower than `%timeit 20.binomial(10)` — previously it was **30** times
slower.

There's also a minor patch where some code is skipped when all arguments
are instances of `Element`. It is certainly a more common case for the
input to be `Element` than otherwise, so we optimize for it.

Another minor patch involves storing imported modules as C global
variables instead of re-import every time.

I think using not-overriding `_method_arguments` as an indicator of
"don't call the method"
(then silently catch `TypeError` and throw it away) is rather bad
design,
but this is not in scope here.

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->

- [x] The title is concise and informative.
- [x] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [x] I have created tests covering the changes.
- [ ] I have updated the documentation and checked the documentation
preview.
    
URL: sagemath#39891
Reported by: user202729
Reviewer(s): Travis Scrimshaw
@vbraun vbraun merged commit b159b4b into sagemath:develop Apr 18, 2025
25 of 27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants