Optimize tuple_slice() and make further improvements to list_slice()

and list.extend().  Factoring the inner loops to remove the constant
structure references and fixed offsets gives speedups ranging from
20% to 30%.
This commit is contained in:
Raymond Hettinger 2004-03-08 07:25:05 +00:00
parent f0e3569a28
commit b7d05db0be
3 changed files with 28 additions and 18 deletions

View File

@ -263,6 +263,9 @@ yellow 5
\begin{itemize}
\item The inner loops for \class{list} and \class{tuple} slicing
were optimized and now run about one-third faster.
\item The machinery for growing and shrinking lists was optimized
for speed and for space efficiency. Small lists (under eight elements)
never over-allocate by more than three elements. Large lists do not

View File

@ -342,6 +342,7 @@ static PyObject *
list_slice(PyListObject *a, int ilow, int ihigh)
{
PyListObject *np;
PyObject **src, **dest;
int i, len;
if (ilow < 0)
ilow = 0;
@ -356,10 +357,12 @@ list_slice(PyListObject *a, int ilow, int ihigh)
if (np == NULL)
return NULL;
src = a->ob_item + ilow;
dest = np->ob_item;
for (i = 0; i < len; i++) {
PyObject *v = a->ob_item[i+ilow];
PyObject *v = src[i];
Py_INCREF(v);
np->ob_item[i] = v;
dest[i] = v;
}
return (PyObject *)np;
}
@ -646,6 +649,7 @@ listextend_internal(PyListObject *self, PyObject *b)
register int selflen = PyList_GET_SIZE(self);
int blen;
register int i;
PyObject **src, **dest;
if (PyObject_Size(b) == 0) {
/* short circuit when b is empty */
@ -678,19 +682,17 @@ listextend_internal(PyListObject *self, PyObject *b)
}
/* populate the end of self with b's items */
if (PyList_Check(b)) {
for (i = 0; i < blen; i++) {
PyObject *o = PyList_GET_ITEM(b, i);
Py_INCREF(o);
PyList_SET_ITEM(self, i+selflen, o);
}
} else {
if (PyList_Check(b))
src = ((PyListObject *)b)->ob_item;
else {
assert (PyTuple_Check(b));
for (i = 0; i < blen; i++) {
PyObject *o = PyTuple_GET_ITEM(b, i);
Py_INCREF(o);
PyList_SET_ITEM(self, i+selflen, o);
}
src = ((PyTupleObject *)b)->ob_item;
}
dest = self->ob_item + selflen;
for (i = 0; i < blen; i++) {
PyObject *o = src[i];
Py_INCREF(o);
dest[i] = o;
}
Py_DECREF(b);
return 0;

View File

@ -306,7 +306,9 @@ static PyObject *
tupleslice(register PyTupleObject *a, register int ilow, register int ihigh)
{
register PyTupleObject *np;
PyObject **src, **dest;
register int i;
int len;
if (ilow < 0)
ilow = 0;
if (ihigh > a->ob_size)
@ -317,13 +319,16 @@ tupleslice(register PyTupleObject *a, register int ilow, register int ihigh)
Py_INCREF(a);
return (PyObject *)a;
}
np = (PyTupleObject *)PyTuple_New(ihigh - ilow);
len = ihigh - ilow;
np = (PyTupleObject *)PyTuple_New(len);
if (np == NULL)
return NULL;
for (i = ilow; i < ihigh; i++) {
PyObject *v = a->ob_item[i];
src = a->ob_item + ilow;
dest = np->ob_item;
for (i = 0; i < len; i++) {
PyObject *v = src[i];
Py_INCREF(v);
np->ob_item[i - ilow] = v;
dest[i] = v;
}
return (PyObject *)np;
}