https://github.com/python/cpython/commit/a3cf0fada09b74b1a6981cc06c4dd0bb1091b092
commit: a3cf0fada09b74b1a6981cc06c4dd0bb1091b092
branch: main
author: Donghee Na <donghee...@python.org>
committer: corona10 <donghee.n...@gmail.com>
date: 2024-03-19T12:18:07+09:00
summary:

gh-116621: Specialize list.extend for dict items (gh-116888)

files:
M Objects/listobject.c

diff --git a/Objects/listobject.c b/Objects/listobject.c
index 096043bb3d3c51..fc20a9bff3af47 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -1289,7 +1289,7 @@ list_extend_set(PyListObject *self, PySetObject *other)
     PyObject **dest = self->ob_item + m;
     while (_PySet_NextEntry((PyObject *)other, &setpos, &key, &hash)) {
         Py_INCREF(key);
-        *dest = key;
+        FT_ATOMIC_STORE_PTR_RELEASE(*dest, key);
         dest++;
     }
     Py_SET_SIZE(self, m + n);
@@ -1312,7 +1312,7 @@ list_extend_dict(PyListObject *self, PyDictObject *dict, 
int which_item)
     while (_PyDict_Next((PyObject *)dict, &pos, &keyvalue[0], &keyvalue[1], 
NULL)) {
         PyObject *obj = keyvalue[which_item];
         Py_INCREF(obj);
-        *dest = obj;
+        FT_ATOMIC_STORE_PTR_RELEASE(*dest, obj);
         dest++;
     }
 
@@ -1320,12 +1320,39 @@ list_extend_dict(PyListObject *self, PyDictObject 
*dict, int which_item)
     return 0;
 }
 
+static int
+list_extend_dictitems(PyListObject *self, PyDictObject *dict)
+{
+    Py_ssize_t m = Py_SIZE(self);
+    Py_ssize_t n = PyDict_GET_SIZE(dict);
+    if (list_resize(self, m + n) < 0) {
+        return -1;
+    }
+
+    PyObject **dest = self->ob_item + m;
+    Py_ssize_t pos = 0;
+    Py_ssize_t i = 0;
+    PyObject *key, *value;
+    while (_PyDict_Next((PyObject *)dict, &pos, &key, &value, NULL)) {
+        PyObject *item = PyTuple_Pack(2, key, value);
+        if (item == NULL) {
+            Py_SET_SIZE(self, m + i);
+            return -1;
+        }
+        FT_ATOMIC_STORE_PTR_RELEASE(*dest, item);
+        dest++;
+        i++;
+    }
+
+    Py_SET_SIZE(self, m + n);
+    return 0;
+}
+
 static int
 _list_extend(PyListObject *self, PyObject *iterable)
 {
     // Special case:
     // lists and tuples which can use PySequence_Fast ops
-    // TODO(@corona10): Add more special cases for other types.
     int res = -1;
     if ((PyObject *)self == iterable) {
         Py_BEGIN_CRITICAL_SECTION(self);
@@ -1359,6 +1386,12 @@ _list_extend(PyListObject *self, PyObject *iterable)
         res = list_extend_dict(self, dict, 1 /*values*/);
         Py_END_CRITICAL_SECTION2();
     }
+    else if (Py_IS_TYPE(iterable, &PyDictItems_Type)) {
+        PyDictObject *dict = ((_PyDictViewObject *)iterable)->dv_dict;
+        Py_BEGIN_CRITICAL_SECTION2(self, dict);
+        res = list_extend_dictitems(self, dict);
+        Py_END_CRITICAL_SECTION2();
+    }
     else {
         Py_BEGIN_CRITICAL_SECTION(self);
         res = list_extend_iter_lock_held(self, iterable);

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to