Skip to content

Speed up math.perm() for large results - #1265

Open
jseop-lim wants to merge 1 commit into
oracle:masterfrom
jseop-lim:fix/math-perm
Open

jseop-lim wants to merge 1 commit into
oracle:masterfrom
jseop-lim:fix/math-perm

Conversation

@jseop-lim

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.

@oracle-contributor-agreement oracle-contributor-agreement Bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Oct 31, 2026
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 <jeongseop_lim@korea.ac.kr>

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

Labels

OCA Verified All contributors have signed the Oracle Contributor Agreement.

1 participant