diff options
author | Pieter Eendebak <pieter.eendebak@gmail.com> | 2022-03-17 23:10:36 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-17 23:10:36 (GMT) |
commit | ac8308d3eaf2526318c1bbf13d4a214fd24605d2 (patch) | |
tree | 5e30e4064ccc5066f357aaebdeea00756e801735 | |
parent | 903f0a02c16240dc769a08c30e8d072a4fb09154 (diff) | |
download | cpython-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.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); |