Skip to content
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Optimize :meth:`dict.fromkeys` and :meth:`frozendict.fromkeys` to avoid
unnecessary thread-safety operations in frozendict cases. Patch by Donghee
Na.
35 changes: 33 additions & 2 deletions Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -3285,14 +3285,22 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value)


if (PyAnyDict_CheckExact(d)) {
Comment thread
corona10 marked this conversation as resolved.
Outdated
if (PyAnyDict_CheckExact(iterable)) {
if (PyDict_CheckExact(iterable)) {
PyDictObject *mp = (PyDictObject *)d;

Py_BEGIN_CRITICAL_SECTION2(d, iterable);
d = (PyObject *)dict_dict_fromkeys(mp, iterable, value);
Py_END_CRITICAL_SECTION2();
return d;
}
else if (PyFrozenDict_CheckExact(iterable)) {
PyDictObject *mp = (PyDictObject *)d;

Py_BEGIN_CRITICAL_SECTION(d);
d = (PyObject *)dict_dict_fromkeys(mp, iterable, value);
Py_END_CRITICAL_SECTION();
return d;
}
else if (PyAnySet_CheckExact(iterable)) {
PyDictObject *mp = (PyDictObject *)d;

Expand All @@ -3302,14 +3310,37 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value)
return d;
}
}
else if (PyFrozenDict_CheckExact(d)) {
if (PyDict_CheckExact(iterable)) {
PyDictObject *mp = (PyDictObject *)d;

Py_BEGIN_CRITICAL_SECTION(iterable);
d = (PyObject *)dict_dict_fromkeys(mp, iterable, value);
Py_END_CRITICAL_SECTION();
return d;
}
else if (PyFrozenDict_CheckExact(iterable)) {
PyDictObject *mp = (PyDictObject *)d;
d = (PyObject *)dict_dict_fromkeys(mp, iterable, value);
return d;
}
else if (PyAnySet_CheckExact(iterable)) {
PyDictObject *mp = (PyDictObject *)d;

Py_BEGIN_CRITICAL_SECTION(iterable);
d = (PyObject *)dict_set_fromkeys(mp, iterable, value);
Py_END_CRITICAL_SECTION();
return d;
}
}

it = PyObject_GetIter(iterable);
if (it == NULL){
Py_DECREF(d);
return NULL;
}

if (PyAnyDict_CheckExact(d)) {
if (PyDict_CheckExact(d)) {
Comment thread
vstinner marked this conversation as resolved.
Py_BEGIN_CRITICAL_SECTION(d);
while ((key = PyIter_Next(it)) != NULL) {
status = setitem_lock_held((PyDictObject *)d, key, value);
Expand Down
Loading