summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPieter Eendebak <pieter.eendebak@gmail.com>2022-03-17 23:10:36 (GMT)
committerGitHub <noreply@github.com>2022-03-17 23:10:36 (GMT)
commitac8308d3eaf2526318c1bbf13d4a214fd24605d2 (patch)
tree5e30e4064ccc5066f357aaebdeea00756e801735
parent903f0a02c16240dc769a08c30e8d072a4fb09154 (diff)
downloadcpython-ac8308d3eaf2526318c1bbf13d4a214fd24605d2.zip
cpython-ac8308d3eaf2526318c1bbf13d4a214fd24605d2.tar.gz
cpython-ac8308d3eaf2526318c1bbf13d4a214fd24605d2.tar.bz2
bpo-47005: Improve performance of bytearray_repeat and bytearray_irepeat (GH-31856)
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2022-03-13-21-04-20.bpo-47005.OHBfCc.rst1
-rw-r--r--Objects/bytearrayobject.c28
2 files changed, 23 insertions, 6 deletions
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 0000000..bf8a4f9
--- /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 3493ff0..ba2d347 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);