8000 bpo-46020: Optimize long_pow for the common case (GH-30555) · python/cpython@fc05e6b · GitHub
[go: up one dir, main page]

Skip to content

Commit fc05e6b

Browse files
authored
bpo-46020: Optimize long_pow for the common case (GH-30555)
This cuts a bit of overhead by not initializing the table of small odd powers unless it's needed for a large exponent.
1 parent e2a9c8e commit fc05e6b

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

Objects/longobject.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4215,8 +4215,13 @@ long_pow(PyObject *v, PyObject *w, PyObject *x)
42154215
/* k-ary values. If the exponent is large enough, table is
42164216
* precomputed so that table[i] == a**(2*i+1) % c for i in
42174217
* range(EXP_TABLE_LEN).
4218+
* Note: this is uninitialzed stack trash: don't pay to set it to known
4219+
* values unless it's needed. Instead ensure that num_table_entries is
4220+
* set to the number of entries actually filled whenever a branch to the
4221+
* Error or Done labels is possible.
42184222
*/
4219-
PyLongObject *table[EXP_TABLE_LEN] = {0};
4223+
PyLongObject *table[EXP_TABLE_LEN];
4224+
Py_ssize_t num_table_entries = 0;
42204225

42214226
/* a, b, c = v, w, x */
42224227
CHECK_BINOP(v, w);
@@ -4408,10 +4413,14 @@ long_pow(PyObject *v, PyObject *w, PyObject *x)
44084413
*/
44094414
Py_INCREF(a);
44104415
table[0] = a;
4416+
num_table_entries = 1;
44114417
MULT(a, a, a2);
44124418
/* table[i] == a**(2*i + 1) % c */
4413-
for (i = 1; i < EXP_TABLE_LEN; ++i)
4419+
for (i = 1; i < EXP_TABLE_LEN; ++i) {
4420+
table[i] = NULL; /* must set to known value for MULT */
44144421
MULT(table[i-1], a2, table[i]);
4422+
++num_table_entries; /* incremented iff MULT succeeded */
4423+
}
44154424
Py_CLEAR(a2);
44164425

44174426
/* Repeatedly extract the next (no more than) EXP_WINDOW_SIZE bits
@@ -4472,10 +4481,8 @@ long_pow(PyObject *v, PyObject *w, PyObject *x)
44724481
Py_CLEAR(z);
44734482
/* fall through */
44744483
Done:
4475-
if (Py_SIZE(b) > HUGE_EXP_CUTOFF / PyLong_SHIFT) {
4476-
for (i = 0; i < EXP_TABLE_LEN; ++i)
4477-
Py_XDECREF(table[i]);
4478-
}
4484+
for (i = 0; i < num_table_entries; ++i)
4485+
Py_DECREF(table[i]);
44794486
Py_DECREF(a);
44804487
Py_DECREF(b);
44814488
Py_XDECREF(c);

0 commit comments

Comments
 (0)
0