FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-141510: Optimize {frozen}dict.fromkeys for frozendict by corona10 · Pull Request #144915 · python/cpython · GitHub

/ cpython Public
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Optimize :meth:`!frozendict.fromkeys` to avoid unnecessary thread-safety operations
in frozendict cases. Patch by Donghee Na.
63 changes: 56 additions & 7 deletions Objects/dictobject.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -2671,10 +2671,8 @@ _PyDict_LoadBuiltinsFromGlobals(PyObject *globals)

/* Consumes references to key and value */
static int
setitem_take2_lock_held(PyDictObject *mp, PyObject *key, PyObject *value)
anydict_setitem_take2(PyDictObject *mp, PyObject *key, PyObject *value)
{
ASSERT_DICT_LOCKED(mp);

assert(key);
assert(value);
assert(PyAnyDict_Check(mp));
Expand All @@ -2693,6 +2691,14 @@ setitem_take2_lock_held(PyDictObject *mp, PyObject *key, PyObject *value)
return insertdict(mp, key, hash, value);
}

/* Consumes references to key and value */
static int
setitem_take2_lock_held(PyDictObject *mp, PyObject *key, PyObject *value)
{
ASSERT_DICT_LOCKED(mp);
return anydict_setitem_take2(mp, key, value);
}

int
_PyDict_SetItem_Take2(PyDictObject *mp, PyObject *key, PyObject *value)
{
Expand Down Expand Up @@ -3284,15 +3290,23 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value)
return NULL;


if (PyAnyDict_CheckExact(d)) {
if (PyAnyDict_CheckExact(iterable)) {
if (PyDict_CheckExact(d)) {
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 +3316,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)) {
Py_BEGIN_CRITICAL_SECTION(d);
while ((key = PyIter_Next(it)) != NULL) {
status = setitem_lock_held((PyDictObject *)d, key, value);
Expand All @@ -3321,7 +3358,19 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value)
}
dict_iter_exit:;
Py_END_CRITICAL_SECTION();
} else {
}
else if (PyFrozenDict_CheckExact(d)) {
while ((key = PyIter_Next(it)) != NULL) {
// anydict_setitem_take2 consumes a reference to key
status = anydict_setitem_take2((PyDictObject *)d,
Comment thread
vstinner marked this conversation as resolved.
key, Py_NewRef(value));
if (status < 0) {
assert(PyErr_Occurred());
goto Fail;
}
}
}
else {
while ((key = PyIter_Next(it)) != NULL) {
status = PyObject_SetItem(d, key, value);
Py_DECREF(key);
Expand Down
Loading

Back | FazBrowse Home | New Git URL