diff options
author | Georg Brandl <georg@python.org> | 2010-12-04 11:02:04 (GMT) |
---|---|---|
committer | Georg Brandl <georg@python.org> | 2010-12-04 11:02:04 (GMT) |
commit | c29cc6a8f27bcbe74772b691a352c8e299a6abfa (patch) | |
tree | 84da71c8ac60efa3d5a9391fcd73dafc27e1a5c5 /Modules | |
parent | 9d8711964f114b9f0f5ed8a9a1eccfba2a096030 (diff) | |
download | cpython-c29cc6a8f27bcbe74772b691a352c8e299a6abfa.zip cpython-c29cc6a8f27bcbe74772b691a352c8e299a6abfa.tar.gz cpython-c29cc6a8f27bcbe74772b691a352c8e299a6abfa.tar.bz2 |
#1569291: speed up array.repeat() by making only O(log n) memcpy() calls; the code follows unicode_repeat.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/arraymodule.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 18e5e66..77a162c 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -674,11 +674,9 @@ array_concat(arrayobject *a, PyObject *bb) static PyObject * array_repeat(arrayobject *a, Py_ssize_t n) { - Py_ssize_t i; Py_ssize_t size; arrayobject *np; - char *p; - Py_ssize_t nbytes; + Py_ssize_t oldbytes, newbytes; if (n < 0) n = 0; if ((Py_SIZE(a) != 0) && (n > PY_SSIZE_T_MAX / Py_SIZE(a))) { @@ -688,13 +686,23 @@ array_repeat(arrayobject *a, Py_ssize_t n) np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr); if (np == NULL) return NULL; - p = np->ob_item; - nbytes = Py_SIZE(a) * a->ob_descr->itemsize; - for (i = 0; i < n; i++) { - memcpy(p, a->ob_item, nbytes); - p += nbytes; + if (n == 0) + return (PyObject *)np; + oldbytes = Py_SIZE(a) * a->ob_descr->itemsize; + newbytes = oldbytes * n; + /* this follows the code in unicode_repeat */ + if (oldbytes == 1) { + memset(np->ob_item, a->ob_item[0], newbytes); + } else { + Py_ssize_t done = oldbytes; + Py_MEMCPY(np->ob_item, a->ob_item, oldbytes); + while (done < newbytes) { + Py_ssize_t ncopy = (done <= newbytes-done) ? done : newbytes-done; + Py_MEMCPY(np->ob_item+done, np->ob_item, ncopy); + done += ncopy; + } } - return (PyObject *) np; + return (PyObject *)np; } static int |