mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
[3.14] gh-132657: avoid locks and refcounting in frozenset lookups (GH-136107) (gh-141772)
gh-132657: avoid locks and refcounting in `frozenset` lookups (GH-136107)
(cherry picked from commit f58a7c7175)
Co-authored-by: Pieter Eendebak <pieter.eendebak@gmail.com>
This commit is contained in:
parent
f6552d2c58
commit
c05e71f61e
2 changed files with 26 additions and 10 deletions
|
|
@ -0,0 +1 @@
|
||||||
|
Improve performance of :class:`frozenset` by removing locks in the free-threading build.
|
||||||
|
|
@ -86,6 +86,8 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
|
||||||
int probes;
|
int probes;
|
||||||
int cmp;
|
int cmp;
|
||||||
|
|
||||||
|
int frozenset = PyFrozenSet_CheckExact(so);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
entry = &so->table[i];
|
entry = &so->table[i];
|
||||||
probes = (i + LINEAR_PROBES <= mask) ? LINEAR_PROBES: 0;
|
probes = (i + LINEAR_PROBES <= mask) ? LINEAR_PROBES: 0;
|
||||||
|
|
@ -102,6 +104,12 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
|
||||||
&& unicode_eq(startkey, key))
|
&& unicode_eq(startkey, key))
|
||||||
return entry;
|
return entry;
|
||||||
table = so->table;
|
table = so->table;
|
||||||
|
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);
|
Py_INCREF(startkey);
|
||||||
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
|
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
|
||||||
Py_DECREF(startkey);
|
Py_DECREF(startkey);
|
||||||
|
|
@ -109,6 +117,7 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (table != so->table || entry->key != startkey)
|
if (table != so->table || entry->key != startkey)
|
||||||
return set_lookkey(so, key, hash);
|
return set_lookkey(so, key, hash);
|
||||||
|
}
|
||||||
if (cmp > 0)
|
if (cmp > 0)
|
||||||
return entry;
|
return entry;
|
||||||
mask = so->mask;
|
mask = so->mask;
|
||||||
|
|
@ -2234,10 +2243,16 @@ set_contains_lock_held(PySetObject *so, PyObject *key)
|
||||||
int
|
int
|
||||||
_PySet_Contains(PySetObject *so, PyObject *key)
|
_PySet_Contains(PySetObject *so, PyObject *key)
|
||||||
{
|
{
|
||||||
|
assert(so);
|
||||||
|
|
||||||
int rv;
|
int rv;
|
||||||
|
if (PyFrozenSet_CheckExact(so)) {
|
||||||
|
rv = set_contains_lock_held(so, key);
|
||||||
|
} else {
|
||||||
Py_BEGIN_CRITICAL_SECTION(so);
|
Py_BEGIN_CRITICAL_SECTION(so);
|
||||||
rv = set_contains_lock_held(so, key);
|
rv = set_contains_lock_held(so, key);
|
||||||
Py_END_CRITICAL_SECTION();
|
Py_END_CRITICAL_SECTION();
|
||||||
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue