diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-06-14-25-00.gh-issue-153199.abc123.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-06-14-25-00.gh-issue-153199.abc123.rst new file mode 100644 index 000000000000000..cde48ce212720a3 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-06-14-25-00.gh-issue-153199.abc123.rst @@ -0,0 +1 @@ +Optimize set and frozenset membership lookup by inlining ``set_do_lookup`` and adding a ``PyUnicode_CheckExact`` fast path to ``set_compare_frozenset``. diff --git a/Objects/setobject.c b/Objects/setobject.c index 8fdd1eb26118c0a..a981849cc859d4a 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -166,8 +166,7 @@ set_compare_entry_lock_held(PySetObject *so, setentry *table, setentry *entry, // This is similar to set_compare_entry_lock_held() but we don't need to // incref startkey before comparing and we don't need to check if the set has -// changed. This also omits the PyUnicode_CheckExact() special case since it -// doesn't help much for frozensets. +// changed. static inline Py_ALWAYS_INLINE int set_compare_frozenset(PySetObject *so, setentry *table, setentry *ep, PyObject *key, Py_hash_t hash) @@ -182,6 +181,11 @@ set_compare_frozenset(PySetObject *so, setentry *table, setentry *ep, } Py_ssize_t ep_hash = ep->hash; if (ep_hash == hash) { + if (PyUnicode_CheckExact(startkey) + && PyUnicode_CheckExact(key) + && unicode_eq(startkey, key)) { + return SET_LOOKKEY_FOUND; + } int cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); if (cmp < 0) { return SET_LOOKKEY_ERROR; @@ -217,7 +221,7 @@ set_zero_table(setentry *table, size_t size) /* This must be >= 1 */ #define PERTURB_SHIFT 5 -static int +static inline Py_ALWAYS_INLINE int set_do_lookup(PySetObject *so, setentry *table, size_t mask, PyObject *key, Py_hash_t hash, setentry **epp, compare_func compare_entry) {