diff options
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2022-03-13-21-04-20.bpo-47005.OHBfCc.rst | 1 | ||||
-rw-r--r-- | Objects/bytearrayobject.c | 28 |
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); |