Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a3cf0fa

Browse files
authored
gh-116621: Specialize list.extend for dict items (gh-116888)
1 parent a22d05f commit a3cf0fa

File tree

1 file changed

+36
-3
lines changed

1 file changed

+36
-3
lines changed

Objects/listobject.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,7 +1289,7 @@ list_extend_set(PyListObject *self, PySetObject *other)
12891289
PyObject **dest = self->ob_item + m;
12901290
while (_PySet_NextEntry((PyObject *)other, &setpos, &key, &hash)) {
12911291
Py_INCREF(key);
1292-
*dest = key;
1292+
FT_ATOMIC_STORE_PTR_RELEASE(*dest, key);
12931293
dest++;
12941294
}
12951295
Py_SET_SIZE(self, m + n);
@@ -1312,20 +1312,47 @@ list_extend_dict(PyListObject *self, PyDictObject *dict, int which_item)
13121312
while (_PyDict_Next((PyObject *)dict, &pos, &keyvalue[0], &keyvalue[1], NULL)) {
13131313
PyObject *obj = keyvalue[which_item];
13141314
Py_INCREF(obj);
1315-
*dest = obj;
1315+
FT_ATOMIC_STORE_PTR_RELEASE(*dest, obj);
13161316
dest++;
13171317
}
13181318

13191319
Py_SET_SIZE(self, m + n);
13201320
return 0;
13211321
}
13221322

1323+
static int
1324+
list_extend_dictitems(PyListObject *self, PyDictObject *dict)
1325+
{
1326+
Py_ssize_t m = Py_SIZE(self);
1327+
Py_ssize_t n = PyDict_GET_SIZE(dict);
1328+
if (list_resize(self, m + n) < 0) {
1329+
return -1;
1330+
}
1331+
1332+
PyObject **dest = self->ob_item + m;
1333+
Py_ssize_t pos = 0;
1334+
Py_ssize_t i = 0;
1335+
PyObject *key, *value;
1336+
while (_PyDict_Next((PyObject *)dict, &pos, &key, &value, NULL)) {
1337+
PyObject *item = PyTuple_Pack(2, key, value);
1338+
if (item == NULL) {
1339+
Py_SET_SIZE(self, m + i);
1340+
return -1;
1341+
}
1342+
FT_ATOMIC_STORE_PTR_RELEASE(*dest, item);
1343+
dest++;
1344+
i++;
1345+
}
1346+
1347+
Py_SET_SIZE(self, m + n);
1348+
return 0;
1349+
}
1350+
13231351
static int
13241352
_list_extend(PyListObject *self, PyObject *iterable)
13251353
{
13261354
// Special case:
13271355
// lists and tuples which can use PySequence_Fast ops
1328-
// TODO(@corona10): Add more special cases for other types.
13291356
int res = -1;
13301357
if ((PyObject *)self == iterable) {
13311358
Py_BEGIN_CRITICAL_SECTION(self);
@@ -1359,6 +1386,12 @@ _list_extend(PyListObject *self, PyObject *iterable)
13591386
res = list_extend_dict(self, dict, 1 /*values*/);
13601387
Py_END_CRITICAL_SECTION2();
13611388
}
1389+
else if (Py_IS_TYPE(iterable, &PyDictItems_Type)) {
1390+
PyDictObject *dict = ((_PyDictViewObject *)iterable)->dv_dict;
1391+
Py_BEGIN_CRITICAL_SECTION2(self, dict);
1392+
res = list_extend_dictitems(self, dict);
1393+
Py_END_CRITICAL_SECTION2();
1394+
}
13621395
else {
13631396
Py_BEGIN_CRITICAL_SECTION(self);
13641397
res = list_extend_iter_lock_held(self, iterable);

0 commit comments

Comments
 (0)