Skip to content

Commit ac8308d

Browse files
authored
bpo-47005: Improve performance of bytearray_repeat and bytearray_irepeat (GH-31856)
1 parent 903f0a0 commit ac8308d

File tree

2 files changed

+23
-6
lines changed

2 files changed

+23
-6
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve performance of ``bytearray_repeat`` and ``bytearray_irepeat`` by reducing the number of invocations of ``memcpy``.

Objects/bytearrayobject.c

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,19 @@ bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
335335
if (mysize == 1)
336336
memset(result->ob_bytes, buf[0], size);
337337
else {
338-
Py_ssize_t i;
339-
for (i = 0; i < count; i++)
340-
memcpy(result->ob_bytes + i*mysize, buf, mysize);
338+
Py_ssize_t i, j;
339+
340+
i = 0;
341+
if (i < size) {
342+
memcpy(result->ob_bytes, buf, mysize);
343+
i = mysize;
344+
}
345+
// repeatedly double the number of bytes copied
346+
while (i < size) {
347+
j = Py_MIN(i, size - i);
348+
memcpy(result->ob_bytes + i, result->ob_bytes, j);
349+
i += j;
350+
}
341351
}
342352
}
343353
return (PyObject *)result;
@@ -363,9 +373,15 @@ bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
363373
if (mysize == 1)
364374
memset(buf, buf[0], size);
365375
else {
366-
Py_ssize_t i;
367-
for (i = 1; i < count; i++)
368-
memcpy(buf + i*mysize, buf, mysize);
376+
Py_ssize_t i, j;
377+
378+
i = mysize;
379+
// repeatedly double the number of bytes copied
380+
while (i < size) {
381+
j = Py_MIN(i, size - i);
382+
memcpy(buf + i, buf, j);
383+
i += j;
384+
}
369385
}
370386

371387
Py_INCREF(self);

0 commit comments

Comments
 (0)