https://github.com/python/cpython/commit/f58a7c717584241467970623384ce61cbd776f29
commit: f58a7c717584241467970623384ce61cbd776f29
branch: main
author: Pieter Eendebak <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2025-08-31T00:55:36+05:30
summary:
gh-132657: avoid locks and refcounting in `frozenset` lookups (#136107)
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2025-07-09-21-27-14.gh-issue-132657.kSA8R3.rst
M Objects/setobject.c
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2025-07-09-21-27-14.gh-issue-132657.kSA8R3.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2025-07-09-21-27-14.gh-issue-132657.kSA8R3.rst
new file mode 100644
index 00000000000000..99f7a990875a0a
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2025-07-09-21-27-14.gh-issue-132657.kSA8R3.rst
@@ -0,0 +1 @@
+Improve performance of :class:`frozenset` by removing locks in the
free-threading build.
diff --git a/Objects/setobject.c b/Objects/setobject.c
index 63ce55e236546f..d8340499be5aae 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -86,6 +86,8 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
int probes;
int cmp;
+ int frozenset = PyFrozenSet_CheckExact(so);
+
while (1) {
entry = &so->table[i];
probes = (i + LINEAR_PROBES <= mask) ? LINEAR_PROBES: 0;
@@ -102,13 +104,20 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t
hash)
&& unicode_eq(startkey, key))
return entry;
table = so->table;
- Py_INCREF(startkey);
- cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
- Py_DECREF(startkey);
- if (cmp < 0)
- return NULL;
- if (table != so->table || entry->key != startkey)
- return set_lookkey(so, key, hash);
+ if (frozenset) {
+ cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
+ if (cmp < 0)
+ return NULL;
+ } else {
+ // incref startkey because it can be removed from the set
by the compare
+ Py_INCREF(startkey);
+ cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
+ Py_DECREF(startkey);
+ if (cmp < 0)
+ return NULL;
+ if (table != so->table || entry->key != startkey)
+ return set_lookkey(so, key, hash);
+ }
if (cmp > 0)
return entry;
mask = so->mask;
@@ -2235,10 +2244,16 @@ set_contains_lock_held(PySetObject *so, PyObject *key)
int
_PySet_Contains(PySetObject *so, PyObject *key)
{
+ assert(so);
+
int rv;
- Py_BEGIN_CRITICAL_SECTION(so);
- rv = set_contains_lock_held(so, key);
- Py_END_CRITICAL_SECTION();
+ if (PyFrozenSet_CheckExact(so)) {
+ rv = set_contains_lock_held(so, key);
+ } else {
+ Py_BEGIN_CRITICAL_SECTION(so);
+ rv = set_contains_lock_held(so, key);
+ Py_END_CRITICAL_SECTION();
+ }
return rv;
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]