8000 gh-129149: Add fast path for medium-size integers in `PyLong_FromSsize_t()` by chris-eibl · Pull Request #129301 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-129149: Add fast path for medium-size integers in PyLong_FromSsize_t() #129301

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Mar 13, 2025
Merged
Prev Previous commit
Next Next commit
address PEP-7 by vertically aligning \
(on a multiple of 4 spaces)
  • Loading branch information
chris-eibl committed Mar 1, 2025
commit f0691c5c9358fe9926d86d814507fc0ed221d9e3
60 changes: 30 additions & 30 deletions Objects/longobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,37 +332,37 @@ _PyLong_Negate(PyLongObject **x_p)
Py_DECREF(x);
}

#define PYLONG_FROM_INT(UINT_TYPE, INT_TYPE, ival) \
do { \
/* Handle small and medium cases. */ \
if (IS_SMALL_INT(ival)) { \
return get_small_int((sdigit)(ival)); \
} \
if (-(INT_TYPE)PyLong_MASK <= (ival) && (ival) <= (INT_TYPE)PyLong_MASK) { \
return _PyLong_FromMedium((sdigit)(ival)); \
} \
#define PYLONG_FROM_INT(UINT_TYPE, INT_TYPE, ival) \
do { \
/* Handle small and medium cases. */ \
if (IS_SMALL_INT(ival)) { \
return get_small_int((sdigit)(ival)); \
} \
if (-(INT_TYPE)PyLong_MASK <= (ival) && (ival) <= (INT_TYPE)PyLong_MASK) { \
return _PyLong_FromMedium((sdigit)(ival)); \
} \
UINT_TYPE abs_ival = (ival) < 0 ? 0U-(UINT_TYPE)(ival) : (UINT_TYPE)(ival); \
/* Do shift in two steps to avoid possible undefined behavior. */ \
UINT_TYPE t = abs_ival >> PyLong_SHIFT >> PyLong_SHIFT; \
/* Count digits (at least two - smaller cases were handled above). */ \
Py_ssize_t ndigits = 2; \
while (t) { \
++ndigits; \
t >>= PyLong_SHIFT; \
} \
/* Construct output value. */ \
PyLongObject *v = long_alloc(ndigits); \
if (v == NULL) { \
return NULL; \
} \
digit *p = v->long_value.ob_digit; \
_PyLong_SetSignAndDigitCount(v, (ival) < 0 ? -1 : 1, ndigits); \
t = abs_ival; \
while (t) { \
*p++ = (digit)(t & PyLong_MASK); \
t >>= PyLong_SHIFT; \
} \
return (PyObject *)v; \
/* Do shift in two steps to avoid possible undefined behavior. */ \
UINT_TYPE t = abs_ival >> PyLong_SHIFT >> PyLong_SHIFT; \
/* Count digits (at least two - smaller cases were handled above). */ \
Py_ssize_t ndigits = 2; \
while (t) { \
++ndigits; \
t >>= PyLong_SHIFT; \
} \
/* Construct output value. */ \
PyLongObject *v = long_alloc(ndigits); \
if (v == NULL) { \
return NULL; \
} \
digit *p = v->long_value.ob_digit; \
_PyLong_SetSignAndDigitCount(v, (ival) < 0 ? -1 : 1, ndigits); \
t = abs_ival; \
while (t) { \
*p++ = (digit)(t & PyLong_MASK); \
t >>= PyLong_SHIFT; \
} \
return (PyObject *)v; \
} while(0)


Expand Down
Loading
0