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 */
|
||||
};
|
||||
|
||||
// Create an set object from dictviews object.
|
||||
// Returns a new reference.
|
||||
// This utility function is used by set operations.
|
||||
static PyObject*
|
||||
dictviews_sub(PyObject* self, PyObject *other)
|
||||
dictviews_to_set(PyObject *self)
|
||||
{
|
||||
PyObject *result = PySet_New(self);
|
||||
PyObject *tmp;
|
||||
_Py_IDENTIFIER(difference_update);
|
||||
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);
|
||||
}
|
||||
|
||||
if (result == NULL)
|
||||
static PyObject*
|
||||
dictviews_sub(PyObject *self, PyObject *other)
|
||||
{
|
||||
PyObject *result = dictviews_to_set(self);
|
||||
if (result == 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) {
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
|
@ -4273,34 +4290,29 @@ error:
|
|||
static PyObject*
|
||||
dictviews_or(PyObject* self, PyObject *other)
|
||||
{
|
||||
PyObject *result = PySet_New(self);
|
||||
PyObject *tmp;
|
||||
_Py_IDENTIFIER(update);
|
||||
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
||||
tmp = _PyObject_CallMethodIdOneArg(result, &PyId_update, other);
|
||||
if (tmp == NULL) {
|
||||
Py_DECREF(result);
|
||||
PyObject *result = dictviews_to_set(self);
|
||||
if (result == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_DECREF(tmp);
|
||||
if (_PySet_Update(result, other) < 0) {
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
dictviews_xor(PyObject* self, PyObject *other)
|
||||
{
|
||||
PyObject *result = PySet_New(self);
|
||||
PyObject *tmp;
|
||||
_Py_IDENTIFIER(symmetric_difference_update);
|
||||
|
||||
if (result == NULL)
|
||||
PyObject *result = dictviews_to_set(self);
|
||||
if (result == 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) {
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in New Issue