]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-136599: Improve long_hash() (#136600)
authorPieter Eendebak <pieter.eendebak@gmail.com>
Thu, 4 Sep 2025 12:27:26 +0000 (14:27 +0200)
committerGitHub <noreply@github.com>
Thu, 4 Sep 2025 12:27:26 +0000 (12:27 +0000)
Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com>
Co-authored-by: Victor Stinner <vstinner@python.org>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Misc/NEWS.d/next/Core_and_Builtins/2025-07-13-21-21-17.gh-issue-136599.sLhm2O.rst [new file with mode: 0644]
Objects/longobject.c

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 (file)
index 0000000..9bcb13f
--- /dev/null
@@ -0,0 +1 @@
+Improve performance of :class:`int` hash calculations.
index b612eabaab480d3ae63963e2f4a584a9f540e2d8..287458ba2da62a5135a4bcb7ca0ef94bf19475b1 100644 (file)
@@ -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