summaryrefslogtreecommitdiffstats
path: root/Objects/longobject.c
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2013-10-06 00:20:18 (GMT)
committerRaymond Hettinger <python@rcn.com>2013-10-06 00:20:18 (GMT)
commit3472fafe745954d1882658f21e54865662f62788 (patch)
treeb2d4640ab49a69f6ecbc0a3de565da5be1c3fa3c /Objects/longobject.c
parentf77cdbeff71b24debf32c9c6605148ae002be5e2 (diff)
parent9259c21a63ea5c342936a18317d455f747248b2f (diff)
downloadcpython-3472fafe745954d1882658f21e54865662f62788.zip
cpython-3472fafe745954d1882658f21e54865662f62788.tar.gz
cpython-3472fafe745954d1882658f21e54865662f62788.tar.bz2
merge
Diffstat (limited to 'Objects/longobject.c')
-rw-r--r--Objects/longobject.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 8748706..876cd19 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -3878,10 +3878,16 @@ long_pow(PyObject *v, PyObject *w, PyObject *x)
goto Done;
}
- /* if base < 0:
- base = base % modulus
- Having the base positive just makes things easier. */
- if (Py_SIZE(a) < 0) {
+ /* Reduce base by modulus in some cases:
+ 1. If base < 0. Forcing the base non-negative makes things easier.
+ 2. If base is obviously larger than the modulus. The "small
+ exponent" case later can multiply directly by base repeatedly,
+ while the "large exponent" case multiplies directly by base 31
+ times. It can be unboundedly faster to multiply by
+ base % modulus instead.
+ We could _always_ do this reduction, but l_divmod() isn't cheap,
+ so we only do it when it buys something. */
+ if (Py_SIZE(a) < 0 || Py_SIZE(a) > Py_SIZE(c)) {
if (l_divmod(a, c, NULL, &temp) < 0)
goto Error;
Py_DECREF(a);