#1569291: speed up array.repeat() by making only O(log n) memcpy() calls; the code follows unicode_repeat.
This commit is contained in:
parent
9d8711964f
commit
c29cc6a8f2
|
@ -504,6 +504,12 @@ class BaseTest(unittest.TestCase):
|
||||||
array.array(self.typecode)
|
array.array(self.typecode)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
a = 5 * array.array(self.typecode, self.example[:1])
|
||||||
|
self.assertEqual(
|
||||||
|
a,
|
||||||
|
array.array(self.typecode, [a[0]] * 5)
|
||||||
|
)
|
||||||
|
|
||||||
self.assertRaises(TypeError, a.__mul__, "bad")
|
self.assertRaises(TypeError, a.__mul__, "bad")
|
||||||
|
|
||||||
def test_imul(self):
|
def test_imul(self):
|
||||||
|
|
|
@ -45,6 +45,8 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #1569291: Speed up array.repeat().
|
||||||
|
|
||||||
- Provide an interface to set the optimization level of compilation in
|
- Provide an interface to set the optimization level of compilation in
|
||||||
py_compile, compileall and zipfile.PyZipFile.
|
py_compile, compileall and zipfile.PyZipFile.
|
||||||
|
|
||||||
|
|
|
@ -674,11 +674,9 @@ array_concat(arrayobject *a, PyObject *bb)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
array_repeat(arrayobject *a, Py_ssize_t n)
|
array_repeat(arrayobject *a, Py_ssize_t n)
|
||||||
{
|
{
|
||||||
Py_ssize_t i;
|
|
||||||
Py_ssize_t size;
|
Py_ssize_t size;
|
||||||
arrayobject *np;
|
arrayobject *np;
|
||||||
char *p;
|
Py_ssize_t oldbytes, newbytes;
|
||||||
Py_ssize_t nbytes;
|
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
n = 0;
|
n = 0;
|
||||||
if ((Py_SIZE(a) != 0) && (n > PY_SSIZE_T_MAX / Py_SIZE(a))) {
|
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);
|
np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
|
||||||
if (np == NULL)
|
if (np == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
p = np->ob_item;
|
if (n == 0)
|
||||||
nbytes = Py_SIZE(a) * a->ob_descr->itemsize;
|
return (PyObject *)np;
|
||||||
for (i = 0; i < n; i++) {
|
oldbytes = Py_SIZE(a) * a->ob_descr->itemsize;
|
||||||
memcpy(p, a->ob_item, nbytes);
|
newbytes = oldbytes * n;
|
||||||
p += nbytes;
|
/* 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
|
static int
|
||||||
|
|
Loading…
Reference in New Issue