From: Pieter Eendebak Date: Thu, 4 Sep 2025 12:27:26 +0000 (+0200) Subject: gh-136599: Improve long_hash() (#136600) X-Git-Tag: v3.15.0a1~493 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c9cf019cf5da57a3eb8835e5f911040efd8665a7;p=thirdparty%2FPython%2Fcpython.git gh-136599: Improve long_hash() (#136600) Co-authored-by: Sergey B Kirpichev Co-authored-by: Victor Stinner Co-authored-by: Serhiy Storchaka --- diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-07-13-21-21-17.gh-issue-136599.sLhm2O.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-07-13-21-21-17.gh-issue-136599.sLhm2O.rst new file mode 100644 index 000000000000..9bcb13f9e20c --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-07-13-21-21-17.gh-issue-136599.sLhm2O.rst @@ -0,0 +1 @@ +Improve performance of :class:`int` hash calculations. diff --git a/Objects/longobject.c b/Objects/longobject.c index b612eabaab48..287458ba2da6 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3676,7 +3676,23 @@ long_hash(PyObject *obj) } i = _PyLong_DigitCount(v); sign = _PyLong_NonCompactSign(v); - x = 0; + + // unroll first digit + Py_BUILD_ASSERT(PyHASH_BITS > PyLong_SHIFT); + assert(i >= 1); + --i; + x = v->long_value.ob_digit[i]; + assert(x < PyHASH_MODULUS); + +#if PyHASH_BITS >= 2 * PyLong_SHIFT + // unroll second digit + assert(i >= 1); + --i; + x <<= PyLong_SHIFT; + x += v->long_value.ob_digit[i]; + assert(x < PyHASH_MODULUS); +#endif + while (--i >= 0) { /* Here x is a quantity in the range [0, _PyHASH_MODULUS); we want to compute x * 2**PyLong_SHIFT + v->long_value.ob_digit[i] modulo