Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9259c21

Browse files
author
Tim Peters
committed
Issue #19171: speed some cases of 3-argument long pow().
Reduce the base by the modulus when the base is larger than the modulus. This can unboundedly speed the "startup costs" of doing modular exponentiation, particularly in cases where the base is much larger than the modulus. Original patch by Armin Rigo, inspired by https://github.com/pyca/ed25519. Merged from 3.3.
2 parents e898153 + 81a9315 commit 9259c21

1 file changed

Lines changed: 10 additions & 4 deletions

File tree

Objects/longobject.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3878,10 +3878,16 @@ long_pow(PyObject *v, PyObject *w, PyObject *x)
38783878
goto Done;
38793879
}
38803880

3881-
/* if base < 0:
3882-
base = base % modulus
3883-
Having the base positive just makes things easier. */
3884-
if (Py_SIZE(a) < 0) {
3881+
/* Reduce base by modulus in some cases:
3882+
1. If base < 0. Forcing the base non-negative makes things easier.
3883+
2. If base is obviously larger than the modulus. The "small
3884+
exponent" case later can multiply directly by base repeatedly,
3885+
while the "large exponent" case multiplies directly by base 31
3886+
times. It can be unboundedly faster to multiply by
3887+
base % modulus instead.
3888+
We could _always_ do this reduction, but l_divmod() isn't cheap,
3889+
so we only do it when it buys something. */
3890+
if (Py_SIZE(a) < 0 || Py_SIZE(a) > Py_SIZE(c)) {
38853891
if (l_divmod(a, c, NULL, &temp) < 0)
38863892
goto Error;
38873893
Py_DECREF(a);

0 commit comments

Comments
 (0)