]> granicus.if.org Git - python/commitdiff
Optimize tuple_slice() and make further improvements to list_slice()
authorRaymond Hettinger <python@rcn.com>
Mon, 8 Mar 2004 07:25:05 +0000 (07:25 +0000)
committerRaymond Hettinger <python@rcn.com>
Mon, 8 Mar 2004 07:25:05 +0000 (07:25 +0000)
and list.extend().  Factoring the inner loops to remove the constant
structure references and fixed offsets gives speedups ranging from
20% to 30%.

Doc/whatsnew/whatsnew24.tex
Objects/listobject.c
Objects/tupleobject.c

index 2a323ff84e08bf52f6c7b6548f61d8d717f942f8..1607cc78fac60d1a6f70230f91b5dc1811b8bb60 100644 (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
index 0508d37b0061a0eb08e7c01a66ea38db47b10219..f5a9c7b087cc148434bf2f1c9771e02485b2bb59 100644 (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;
index ef5cb8518b3ab105ffd56956dea913565ae6ae32..eaf3c88b1d4770ddc16b788b17e40c40db826fad 100644 (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;
 }