From: Neil Schemenauer Date: Fri, 3 Apr 2026 06:34:06 +0000 (-0700) Subject: GH-147985: Use lock-free lookup in `PySet_Contains` (#147986) X-Git-Tag: v3.15.0a8~64 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9d087d6d41e1eaa0d1b9612ba65c5a4fb6aca098;p=thirdparty%2FPython%2Fcpython.git GH-147985: Use lock-free lookup in `PySet_Contains` (#147986) Co-authored-by: Kumar Aditya --- diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-04-01-12-35-55.gh-issue-147985.YVirHJ.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-04-01-12-35-55.gh-issue-147985.YVirHJ.rst new file mode 100644 index 000000000000..a94dfca5e2a4 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-04-01-12-35-55.gh-issue-147985.YVirHJ.rst @@ -0,0 +1,3 @@ +Make :c:func:`PySet_Contains` attempt a lock-free lookup, similar to +:meth:`!set.__contains__`. This avoids acquiring the set object mutex in the +normal case. diff --git a/Objects/setobject.c b/Objects/setobject.c index ae6c1d1248d2..1e6305636045 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -3023,14 +3023,14 @@ PySet_Contains(PyObject *anyset, PyObject *key) PyErr_BadInternalCall(); return -1; } - if (PyFrozenSet_CheckExact(anyset)) { - return set_contains_key((PySetObject *)anyset, key); + + PySetObject *so = (PySetObject *)anyset; + Py_hash_t hash = _PyObject_HashFast(key); + if (hash == -1) { + set_unhashable_type(key); + return -1; } - int rv; - Py_BEGIN_CRITICAL_SECTION(anyset); - rv = set_contains_key((PySetObject *)anyset, key); - Py_END_CRITICAL_SECTION(); - return rv; + return set_contains_entry(so, key, hash); } int