GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Speed up `math.perm()` for large results by jseop-lim · Pull Request #1265 · oracle/graalpython

Conversation

@jseop-lim

@jseop-lim jseop-lim commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes #1254

math.perm(n, k) multiplied the running product by one factor at a time, so its cost grew with the square of the result size and BigInteger.multiply never got two large operands. CPython splits the product as P(n, k) = P(n, j) * P(n - j, k - j) with j = k / 2 (mathmodule.c#L3634-L3649), so the large multiplications are between operands of similar size.

AS-IS

>>> t = time.time(); n = math.perm(615913, 286885); print(n.bit_length(), round(time.time() - t, 1))
5401202 27.6

TO-BE

5401202 0.3

Timings for math.perm(615913, 286885) on macOS arm64:

Build Time
master, mx python-jvm (interpreted JVM) 27.6 s
this PR, mx python-jvm (interpreted JVM) 0.34 s
GraalPy 25.1.3 release (native) 35.6 s
CPython 3.13.14 1.4 s

Changes

  • Compute P(n, k) in PermNode by recursive halving instead of the sequential loop.
  • Add test_perm_matches_product in a new tests/test_math_perm.py.

Testing

mx python-jvm on darwin-aarch64, then --tagged test_math (79 passed, same as master). The new test passes before and after the change; it checks values, not time. math.perm(n, k) equals factorial(n) // factorial(n - k) for every n < 60 and every k.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@oracle-contributor-agreement oracle-contributor-agreement Bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Oct 31, 2026
@jseop-lim
Speed up math.perm() for large k
d99ac7a
calculatePerm multiplied the k factors one at a time into a growing
product, so each step was a big-by-small multiplication and the whole
loop was quadratic in the result size. math.perm(615913, 286885) took
about 28 s on a JVM build against about 1 s on CPython. Splitting the
range in halves keeps the operands of each multiplication balanced, so
BigInteger can use its faster algorithms; the same call now takes
0.3 s.

Signed-off-by: Jeongseop Lim <[email protected]>
@jseop-lim
jseop-lim force-pushed the fix/math-perm branch from e10ec09 to d99ac7a Compare October 31, 2026 11:51
msimacek
msimacek reviewed Nov 9, 2026
View reviewed changes
Comment thread graalpython/com.oracle.graal.python.test/src/tests/test_math_perm.py
import math


def test_perm_matches_product():

@msimacek msimacek Nov 9, 2026

Copy link
Copy Markdown
Contributor

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 move the test into test_math

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@msimacek msimacek msimacek left review comments

At least 1 approving review is required to merge this pull request.

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

OCA Verified All contributors have signed the Oracle Contributor Agreement.

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

[Bug]: math.perm is quadratic in the result size, 50 to 100 times slower than CPython for large results

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@jseop-lim @msimacek
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.