[Python-checkins] bpo-46993: Speed up bytearray creation from list and tuple (GH-31834)

asvetlov webhook-mailer at python.org
Tue Mar 15 09:27:35 EDT 2022


https://github.com/python/cpython/commit/6dfe09fc5fd5a3ddc6009d5656e635eae30c5240
commit: 6dfe09fc5fd5a3ddc6009d5656e635eae30c5240
branch: main
author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com>
committer: asvetlov <andrew.svetlov at gmail.com>
date: 2022-03-15T15:27:30+02:00
summary:

bpo-46993: Speed up bytearray creation from list and tuple (GH-31834)

files:
A Misc/NEWS.d/next/Core and Builtins/2022-03-12-09-44-31.bpo-46993.-13hGo.rst
M Objects/bytearrayobject.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-12-09-44-31.bpo-46993.-13hGo.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-12-09-44-31.bpo-46993.-13hGo.rst
new file mode 100644
index 0000000000000..b7f7078856bd5
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-12-09-44-31.bpo-46993.-13hGo.rst	
@@ -0,0 +1 @@
+Speed up :class:`bytearray` creation from :class:`list` and :class:`tuple` by 40%. Patch by Kumar Aditya.
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c
index 0ebb2ece39d5d..3493ff046ae13 100644
--- a/Objects/bytearrayobject.c
+++ b/Objects/bytearrayobject.c
@@ -844,8 +844,33 @@ bytearray___init___impl(PyByteArrayObject *self, PyObject *arg,
         return -1;
     }
 
-    /* XXX Optimize this if the arguments is a list, tuple */
-
+    if (PyList_CheckExact(arg) || PyTuple_CheckExact(arg)) {
+        Py_ssize_t size = PySequence_Fast_GET_SIZE(arg);
+        if (PyByteArray_Resize((PyObject *)self, size) < 0) {
+            return -1;
+        }
+        PyObject **items = PySequence_Fast_ITEMS(arg);
+        char *s = PyByteArray_AS_STRING(self);
+        for (Py_ssize_t i = 0; i < size; i++) {
+            int value;
+            if (!PyLong_CheckExact(items[i])) {
+                /* Resize to 0 and go through slowpath */
+                if (Py_SIZE(self) != 0) {
+                   if (PyByteArray_Resize((PyObject *)self, 0) < 0) {
+                       return -1;
+                   }
+                }
+                goto slowpath;
+            }
+            int rc = _getbytevalue(items[i], &value);
+            if (!rc) {
+                return -1;
+            }
+            s[i] = value;
+        }
+        return 0;
+    }
+slowpath:
     /* Get the iterator */
     it = PyObject_GetIter(arg);
     if (it == NULL) {



More information about the Python-checkins mailing list