]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-47005: Improve performance of bytearray_repeat and bytearray_irepeat (GH-31856)
authorPieter Eendebak <pieter.eendebak@gmail.com>
Thu, 17 Mar 2022 23:10:36 +0000 (00:10 +0100)
committerGitHub <noreply@github.com>
Thu, 17 Mar 2022 23:10:36 +0000 (19:10 -0400)
Misc/NEWS.d/next/Core and Builtins/2022-03-13-21-04-20.bpo-47005.OHBfCc.rst [new file with mode: 0644]
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 (file)
index 0000000..bf8a4f9
--- /dev/null
@@ -0,0 +1 @@
+Improve performance of ``bytearray_repeat`` and ``bytearray_irepeat`` by reducing the number of invocations of ``memcpy``.
index 3493ff046ae139822079a7a75dbaa336fb449b48..ba2d347dbd7a87c2ad3879820ce19c7c869c4221 100644 (file)
@@ -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);