From ac8308d3eaf2526318c1bbf13d4a214fd24605d2 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Fri, 18 Mar 2022 00:10:36 +0100 Subject: bpo-47005: Improve performance of bytearray_repeat and bytearray_irepeat (GH-31856) --- .../2022-03-13-21-04-20.bpo-47005.OHBfCc.rst | 1 + Objects/bytearrayobject.c | 28 +++++++++++++++++----- 2 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-03-13-21-04-20.bpo-47005.OHBfCc.rst 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); -- cgit v0.12