From: Pieter Eendebak Date: Thu, 17 Mar 2022 23:10:36 +0000 (+0100) Subject: bpo-47005: Improve performance of bytearray_repeat and bytearray_irepeat (GH-31856) X-Git-Tag: v3.11.0a7~207 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ac8308d3eaf2526318c1bbf13d4a214fd24605d2;p=thirdparty%2FPython%2Fcpython.git bpo-47005: Improve performance of bytearray_repeat and bytearray_irepeat (GH-31856) --- 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 000000000000..bf8a4f92a1e7 --- /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 3493ff046ae1..ba2d347dbd7a 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);