[Python-checkins] bpo-47005: Improve performance of bytearray_repeat and bytearray_irepeat (GH-31856)

sweeneyde webhook-mailer at python.org
Thu Mar 17 19:10:56 EDT 2022


https://github.com/python/cpython/commit/ac8308d3eaf2526318c1bbf13d4a214fd24605d2
commit: ac8308d3eaf2526318c1bbf13d4a214fd24605d2
branch: main
author: Pieter Eendebak <pieter.eendebak at gmail.com>
committer: sweeneyde <36520290+sweeneyde at users.noreply.github.com>
date: 2022-03-17T19:10:36-04:00
summary:

bpo-47005: Improve performance of bytearray_repeat and bytearray_irepeat (GH-31856)

files:
A Misc/NEWS.d/next/Core and Builtins/2022-03-13-21-04-20.bpo-47005.OHBfCc.rst
M Objects/bytearrayobject.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-13-21-04-20.bpo-47005.OHBfCc.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-13-21-04-20.bpo-47005.OHBfCc.rst
new file mode 100644
index 0000000000000..bf8a4f92a1e7f
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-13-21-04-20.bpo-47005.OHBfCc.rst	
@@ -0,0 +1 @@
+Improve performance of ``bytearray_repeat`` and ``bytearray_irepeat`` by reducing the number of invocations of ``memcpy``.
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c
index 3493ff046ae13..ba2d347dbd7a8 100644
--- a/Objects/bytearrayobject.c
+++ b/Objects/bytearrayobject.c
@@ -335,9 +335,19 @@ bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
         if (mysize == 1)
             memset(result->ob_bytes, buf[0], size);
         else {
-            Py_ssize_t i;
-            for (i = 0; i < count; i++)
-                memcpy(result->ob_bytes + i*mysize, buf, mysize);
+            Py_ssize_t i, j;
+
+            i = 0;
+            if (i < size) {
+                memcpy(result->ob_bytes, buf, mysize);
+                i = mysize;
+            }
+            // repeatedly double the number of bytes copied
+            while (i < size) {
+                j = Py_MIN(i, size - i);
+                memcpy(result->ob_bytes + i, result->ob_bytes, j);
+                i += j;
+            }
         }
     }
     return (PyObject *)result;
@@ -363,9 +373,15 @@ bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
     if (mysize == 1)
         memset(buf, buf[0], size);
     else {
-        Py_ssize_t i;
-        for (i = 1; i < count; i++)
-            memcpy(buf + i*mysize, buf, mysize);
+        Py_ssize_t i, j;
+
+        i = mysize;
+        // repeatedly double the number of bytes copied
+        while (i < size) {
+            j = Py_MIN(i, size - i);
+            memcpy(buf + i, buf, j);
+            i += j;
+        }
     }
 
     Py_INCREF(self);



More information about the Python-checkins mailing list