mirror of
https://github.com/python/cpython.git
synced 2025-11-03 11:23:31 +00:00
bpo-34151: Improve performance of some list operations (GH-8332)
This commit is contained in:
parent
9e84084851
commit
2fc46979b8
2 changed files with 37 additions and 14 deletions
|
|
@ -0,0 +1,2 @@
|
||||||
|
Performance of list concatenation, repetition and slicing operations is
|
||||||
|
slightly improved. Patch by Sergey Fedoseev.
|
||||||
|
|
@ -180,6 +180,23 @@ PyList_New(Py_ssize_t size)
|
||||||
return (PyObject *) op;
|
return (PyObject *) op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list_new_prealloc(Py_ssize_t size)
|
||||||
|
{
|
||||||
|
PyListObject *op = (PyListObject *) PyList_New(0);
|
||||||
|
if (size == 0 || op == NULL) {
|
||||||
|
return (PyObject *) op;
|
||||||
|
}
|
||||||
|
assert(op->ob_item == NULL);
|
||||||
|
op->ob_item = PyMem_New(PyObject *, size);
|
||||||
|
if (op->ob_item == NULL) {
|
||||||
|
Py_DECREF(op);
|
||||||
|
return PyErr_NoMemory();
|
||||||
|
}
|
||||||
|
op->allocated = size;
|
||||||
|
return (PyObject *) op;
|
||||||
|
}
|
||||||
|
|
||||||
Py_ssize_t
|
Py_ssize_t
|
||||||
PyList_Size(PyObject *op)
|
PyList_Size(PyObject *op)
|
||||||
{
|
{
|
||||||
|
|
@ -438,7 +455,7 @@ list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
|
||||||
else if (ihigh > Py_SIZE(a))
|
else if (ihigh > Py_SIZE(a))
|
||||||
ihigh = Py_SIZE(a);
|
ihigh = Py_SIZE(a);
|
||||||
len = ihigh - ilow;
|
len = ihigh - ilow;
|
||||||
np = (PyListObject *) PyList_New(len);
|
np = (PyListObject *) list_new_prealloc(len);
|
||||||
if (np == NULL)
|
if (np == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
@ -449,6 +466,7 @@ list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
|
||||||
Py_INCREF(v);
|
Py_INCREF(v);
|
||||||
dest[i] = v;
|
dest[i] = v;
|
||||||
}
|
}
|
||||||
|
Py_SIZE(np) = len;
|
||||||
return (PyObject *)np;
|
return (PyObject *)np;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -479,7 +497,7 @@ list_concat(PyListObject *a, PyObject *bb)
|
||||||
if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b))
|
if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b))
|
||||||
return PyErr_NoMemory();
|
return PyErr_NoMemory();
|
||||||
size = Py_SIZE(a) + Py_SIZE(b);
|
size = Py_SIZE(a) + Py_SIZE(b);
|
||||||
np = (PyListObject *) PyList_New(size);
|
np = (PyListObject *) list_new_prealloc(size);
|
||||||
if (np == NULL) {
|
if (np == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -497,6 +515,7 @@ list_concat(PyListObject *a, PyObject *bb)
|
||||||
Py_INCREF(v);
|
Py_INCREF(v);
|
||||||
dest[i] = v;
|
dest[i] = v;
|
||||||
}
|
}
|
||||||
|
Py_SIZE(np) = size;
|
||||||
return (PyObject *)np;
|
return (PyObject *)np;
|
||||||
#undef b
|
#undef b
|
||||||
}
|
}
|
||||||
|
|
@ -516,19 +535,19 @@ list_repeat(PyListObject *a, Py_ssize_t n)
|
||||||
size = Py_SIZE(a) * n;
|
size = Py_SIZE(a) * n;
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return PyList_New(0);
|
return PyList_New(0);
|
||||||
np = (PyListObject *) PyList_New(size);
|
np = (PyListObject *) list_new_prealloc(size);
|
||||||
if (np == NULL)
|
if (np == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
items = np->ob_item;
|
|
||||||
if (Py_SIZE(a) == 1) {
|
if (Py_SIZE(a) == 1) {
|
||||||
|
items = np->ob_item;
|
||||||
elem = a->ob_item[0];
|
elem = a->ob_item[0];
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
items[i] = elem;
|
items[i] = elem;
|
||||||
Py_INCREF(elem);
|
Py_INCREF(elem);
|
||||||
}
|
}
|
||||||
return (PyObject *) np;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
p = np->ob_item;
|
p = np->ob_item;
|
||||||
items = a->ob_item;
|
items = a->ob_item;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
|
|
@ -538,6 +557,8 @@ list_repeat(PyListObject *a, Py_ssize_t n)
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
Py_SIZE(np) = size;
|
||||||
return (PyObject *) np;
|
return (PyObject *) np;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2738,7 +2759,7 @@ list_subscript(PyListObject* self, PyObject* item)
|
||||||
return list_slice(self, start, stop);
|
return list_slice(self, start, stop);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = PyList_New(slicelength);
|
result = list_new_prealloc(slicelength);
|
||||||
if (!result) return NULL;
|
if (!result) return NULL;
|
||||||
|
|
||||||
src = self->ob_item;
|
src = self->ob_item;
|
||||||
|
|
@ -2749,7 +2770,7 @@ list_subscript(PyListObject* self, PyObject* item)
|
||||||
Py_INCREF(it);
|
Py_INCREF(it);
|
||||||
dest[i] = it;
|
dest[i] = it;
|
||||||
}
|
}
|
||||||
|
Py_SIZE(result) = slicelength;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue