From a69a4a917c436579c2c4112081ea86a70f1f05d3 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 6 Apr 2022 19:57:13 +0300 Subject: bpo-46721: Optimize set.issuperset() for non-set arguments (GH-31280) --- .../2022-02-11-17-16-30.bpo-46721.JkHaLF.rst | 1 + Objects/setobject.c | 39 +++++++++++++--------- 2 files changed, 24 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-02-11-17-16-30.bpo-46721.JkHaLF.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-11-17-16-30.bpo-46721.JkHaLF.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-11-17-16-30.bpo-46721.JkHaLF.rst new file mode 100644 index 0000000..5644f10 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-02-11-17-16-30.bpo-46721.JkHaLF.rst @@ -0,0 +1 @@ +Optimize :meth:`set.issuperset` for non-set argument. diff --git a/Objects/setobject.c b/Objects/setobject.c index 18dc49b..ef2190d 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1382,14 +1382,7 @@ set_isdisjoint(PySetObject *so, PyObject *other) return NULL; while ((key = PyIter_Next(it)) != NULL) { - Py_hash_t hash = PyObject_Hash(key); - - if (hash == -1) { - Py_DECREF(key); - Py_DECREF(it); - return NULL; - } - rv = set_contains_entry(so, key, hash); + rv = set_contains_key(so, key); Py_DECREF(key); if (rv < 0) { Py_DECREF(it); @@ -1773,17 +1766,31 @@ PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set."); static PyObject * set_issuperset(PySetObject *so, PyObject *other) { - PyObject *tmp, *result; + if (PyAnySet_Check(other)) { + return set_issubset((PySetObject *)other, (PyObject *)so); + } - if (!PyAnySet_Check(other)) { - tmp = make_new_set(&PySet_Type, other); - if (tmp == NULL) + PyObject *key, *it = PyObject_GetIter(other); + if (it == NULL) { + return NULL; + } + while ((key = PyIter_Next(it)) != NULL) { + int rv = set_contains_key(so, key); + Py_DECREF(key); + if (rv < 0) { + Py_DECREF(it); return NULL; - result = set_issuperset(so, tmp); - Py_DECREF(tmp); - return result; + } + if (!rv) { + Py_DECREF(it); + Py_RETURN_FALSE; + } } - return set_issubset((PySetObject *)other, (PyObject *)so); + Py_DECREF(it); + if (PyErr_Occurred()) { + return NULL; + } + Py_RETURN_TRUE; } PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set."); -- cgit v0.12