mirror of https://github.com/python/cpython.git
bpo-38613: Optimize set operations of dict keys. (GH-16961)
This commit is contained in:
parent
d12d0e7c0f
commit
6cbc84fb99
|
@ -0,0 +1,3 @@
|
||||||
|
Optimized some set operations (e.g. ``|``, ``^``, and ``-``) of
|
||||||
|
``dict_keys``. ``d.keys() | other`` was slower than ``set(d) | other`` but
|
||||||
|
they are almost same performance for now.
|
|
@ -4162,17 +4162,34 @@ static PySequenceMethods dictkeys_as_sequence = {
|
||||||
(objobjproc)dictkeys_contains, /* sq_contains */
|
(objobjproc)dictkeys_contains, /* sq_contains */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Create an set object from dictviews object.
|
||||||
|
// Returns a new reference.
|
||||||
|
// This utility function is used by set operations.
|
||||||
|
static PyObject*
|
||||||
|
dictviews_to_set(PyObject *self)
|
||||||
|
{
|
||||||
|
PyObject *left = self;
|
||||||
|
if (PyDictKeys_Check(self)) {
|
||||||
|
// PySet_New() has fast path for the dict object.
|
||||||
|
PyObject *dict = (PyObject *)((_PyDictViewObject *)self)->dv_dict;
|
||||||
|
if (PyDict_CheckExact(dict)) {
|
||||||
|
left = dict;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PySet_New(left);
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
dictviews_sub(PyObject *self, PyObject *other)
|
dictviews_sub(PyObject *self, PyObject *other)
|
||||||
{
|
{
|
||||||
PyObject *result = PySet_New(self);
|
PyObject *result = dictviews_to_set(self);
|
||||||
PyObject *tmp;
|
if (result == NULL) {
|
||||||
_Py_IDENTIFIER(difference_update);
|
|
||||||
|
|
||||||
if (result == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
tmp = _PyObject_CallMethodIdOneArg(result, &PyId_difference_update, other);
|
_Py_IDENTIFIER(difference_update);
|
||||||
|
PyObject *tmp = _PyObject_CallMethodIdOneArg(
|
||||||
|
result, &PyId_difference_update, other);
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -4273,34 +4290,29 @@ _PyDictView_Intersect(PyObject* self, PyObject *other)
|
||||||
static PyObject*
|
static PyObject*
|
||||||
dictviews_or(PyObject* self, PyObject *other)
|
dictviews_or(PyObject* self, PyObject *other)
|
||||||
{
|
{
|
||||||
PyObject *result = PySet_New(self);
|
PyObject *result = dictviews_to_set(self);
|
||||||
PyObject *tmp;
|
if (result == NULL) {
|
||||||
_Py_IDENTIFIER(update);
|
|
||||||
|
|
||||||
if (result == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
tmp = _PyObject_CallMethodIdOneArg(result, &PyId_update, other);
|
|
||||||
if (tmp == NULL) {
|
|
||||||
Py_DECREF(result);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_DECREF(tmp);
|
if (_PySet_Update(result, other) < 0) {
|
||||||
|
Py_DECREF(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
dictviews_xor(PyObject* self, PyObject *other)
|
dictviews_xor(PyObject* self, PyObject *other)
|
||||||
{
|
{
|
||||||
PyObject *result = PySet_New(self);
|
PyObject *result = dictviews_to_set(self);
|
||||||
PyObject *tmp;
|
if (result == NULL) {
|
||||||
_Py_IDENTIFIER(symmetric_difference_update);
|
|
||||||
|
|
||||||
if (result == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
tmp = _PyObject_CallMethodIdOneArg(result, &PyId_symmetric_difference_update, other);
|
_Py_IDENTIFIER(symmetric_difference_update);
|
||||||
|
PyObject *tmp = _PyObject_CallMethodIdOneArg(
|
||||||
|
result, &PyId_symmetric_difference_update, other);
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in New Issue