]> granicus.if.org Git - python/commitdiff
Optimize inner loops for subscript, repeat, and concat.
authorRaymond Hettinger <python@rcn.com>
Tue, 9 Mar 2004 13:05:22 +0000 (13:05 +0000)
committerRaymond Hettinger <python@rcn.com>
Tue, 9 Mar 2004 13:05:22 +0000 (13:05 +0000)
Objects/listobject.c
Objects/tupleobject.c

index fd0dc70438c0ea2e4fd5978ab6831f3ef62b2fce..47f4a37b9984c8cf74c1ef021076a3ebc05a9fef 100644 (file)
@@ -382,6 +382,7 @@ list_concat(PyListObject *a, PyObject *bb)
 {
        int size;
        int i;
+       PyObject **src, **dest;
        PyListObject *np;
        if (!PyList_Check(bb)) {
                PyErr_Format(PyExc_TypeError,
@@ -397,15 +398,19 @@ list_concat(PyListObject *a, PyObject *bb)
        if (np == NULL) {
                return NULL;
        }
+       src = a->ob_item;
+       dest = np->ob_item;
        for (i = 0; i < a->ob_size; i++) {
-               PyObject *v = a->ob_item[i];
+               PyObject *v = src[i];
                Py_INCREF(v);
-               np->ob_item[i] = v;
+               dest[i] = v;
        }
+       src = b->ob_item;
+       dest = np->ob_item + a->ob_size;
        for (i = 0; i < b->ob_size; i++) {
-               PyObject *v = b->ob_item[i];
+               PyObject *v = src[i];
                Py_INCREF(v);
-               np->ob_item[i + a->ob_size] = v;
+               dest[i] = v;
        }
        return (PyObject *)np;
 #undef b
@@ -417,7 +422,7 @@ list_repeat(PyListObject *a, int n)
        int i, j;
        int size;
        PyListObject *np;
-       PyObject **p;
+       PyObject **p, **items;
        PyObject *elem;
        if (n < 0)
                n = 0;
@@ -430,18 +435,20 @@ list_repeat(PyListObject *a, int n)
        if (np == NULL)
                return NULL;
 
+       items = np->ob_item;
        if (a->ob_size == 1) {
                elem = a->ob_item[0];
                for (i = 0; i < n; i++) {
-                       np->ob_item[i] = elem;
+                       items[i] = elem;
                        Py_INCREF(elem);
                }
                return (PyObject *) np;
        }
        p = np->ob_item;
+       items = a->ob_item;
        for (i = 0; i < n; i++) {
                for (j = 0; j < a->ob_size; j++) {
-                       *p = a->ob_item[j];
+                       *p = items[j];
                        Py_INCREF(*p);
                        p++;
                }
@@ -590,11 +597,12 @@ list_inplace_repeat(PyListObject *self, int n)
                return NULL;
 
        p = size;
+       items = self->ob_item;
        for (i = 1; i < n; i++) { /* Start counting at 1, not 0 */
                for (j = 0; j < size; j++) {
-                       PyObject *o = PyList_GET_ITEM(self, j);
+                       PyObject *o = items[j];
                        Py_INCREF(o);
-                       PyList_SET_ITEM(self, p++, o);
+                       items[p++] = o;
                }
        }
        Py_INCREF(self);
@@ -2404,6 +2412,7 @@ list_subscript(PyListObject* self, PyObject* item)
                int start, stop, step, slicelength, cur, i;
                PyObject* result;
                PyObject* it;
+               PyObject **src, **dest;
 
                if (PySlice_GetIndicesEx((PySliceObject*)item, self->ob_size,
                                 &start, &stop, &step, &slicelength) < 0) {
@@ -2417,11 +2426,13 @@ list_subscript(PyListObject* self, PyObject* item)
                        result = PyList_New(slicelength);
                        if (!result) return NULL;
 
+                       src = self->ob_item;
+                       dest = ((PyListObject *)result)->ob_item;
                        for (cur = start, i = 0; i < slicelength;
                             cur += step, i++) {
-                               it = PyList_GET_ITEM(self, cur);
+                               it = src[cur];
                                Py_INCREF(it);
-                               PyList_SET_ITEM(result, i, it);
+                               dest[i] = it;
                        }
 
                        return result;
@@ -2466,7 +2477,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value)
                if (value == NULL) {
                        /* delete slice */
                        PyObject **garbage;
-                       int cur, i, j;
+                       int cur, i;
 
                        if (slicelength <= 0)
                                return 0;
@@ -2493,17 +2504,17 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value)
                                        lim = self->ob_size - cur - 1;
                                }
 
-                               for (j = 0; j < lim; j++) {
-                                       PyList_SET_ITEM(self, cur + j - i,
-                                               PyList_GET_ITEM(self,
-                                                               cur + j + 1));
-                               }
+                               memmove(self->ob_item + cur - i, 
+                                       self->ob_item + cur + 1,
+                                       lim * sizeof(PyObject *));
                        }
+
                        for (cur = start + slicelength*step + 1;
                             cur < self->ob_size; cur++) {
                                PyList_SET_ITEM(self, cur - slicelength,
                                                PyList_GET_ITEM(self, cur));
                        }
+
                        self->ob_size -= slicelength;
                        list_resize(self, self->ob_size);
 
@@ -2516,7 +2527,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value)
                }
                else {
                        /* assign slice */
-                       PyObject **garbage, *ins, *seq;
+                       PyObject **garbage, *ins, *seq, **seqitems, **selfitems;
                        int cur, i;
 
                        /* protect against a[::-1] = a */
@@ -2525,11 +2536,8 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value)
                                                   PyList_GET_SIZE(value));
                        }
                        else {
-                               char msg[256];
-                               PyOS_snprintf(msg, sizeof(msg),
-                     "must assign sequence (not \"%.200s\") to extended slice",
-                                             value->ob_type->tp_name);
-                               seq = PySequence_Fast(value, msg);
+                               seq = PySequence_Fast(value, 
+                                       "must assign iterable to extended slice");
                                if (!seq)
                                        return -1;
                        }
@@ -2551,13 +2559,17 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value)
                        garbage = (PyObject**)
                                PyMem_MALLOC(slicelength*sizeof(PyObject*));
 
+                       selfitems = self->ob_item;
+                       if (PyList_Check(seq))
+                               seqitems = ((PyListObject *)seq)->ob_item;
+                       else
+                               seqitems = ((PyTupleObject *)seq)->ob_item;
                        for (cur = start, i = 0; i < slicelength;
                             cur += step, i++) {
-                               garbage[i] = PyList_GET_ITEM(self, cur);
-
-                               ins = PySequence_Fast_GET_ITEM(seq, i);
+                               garbage[i] = selfitems[cur];
+                               ins = seqitems[i];
                                Py_INCREF(ins);
-                               PyList_SET_ITEM(self, cur, ins);
+                               selfitems[cur] = ins;
                        }
 
                        for (i = 0; i < slicelength; i++) {
index eaf3c88b1d4770ddc16b788b17e40c40db826fad..2d494484e04519b2daa6252f0160c85c443835cf 100644 (file)
@@ -136,16 +136,18 @@ PyTuple_Pack(int n, ...)
        int i;
        PyObject *o;
        PyObject *result;
+       PyObject **items;
        va_list vargs;
 
        va_start(vargs, n);
        result = PyTuple_New(n);
        if (result == NULL)
                return NULL;
+       items = ((PyTupleObject *)result)->ob_item;
        for (i = 0; i < n; i++) {
                o = va_arg(vargs, PyObject *);
                Py_INCREF(o);
-               PyTuple_SET_ITEM(result, i, o);
+               items[i] = o;
        }
        va_end(vargs);
        return result;
@@ -348,6 +350,7 @@ tupleconcat(register PyTupleObject *a, register PyObject *bb)
 {
        register int size;
        register int i;
+       PyObject **src, **dest;
        PyTupleObject *np;
        if (!PyTuple_Check(bb)) {
                PyErr_Format(PyExc_TypeError,
@@ -363,15 +366,19 @@ tupleconcat(register PyTupleObject *a, register PyObject *bb)
        if (np == NULL) {
                return NULL;
        }
+       src = a->ob_item;
+       dest = np->ob_item;
        for (i = 0; i < a->ob_size; i++) {
-               PyObject *v = a->ob_item[i];
+               PyObject *v = src[i];
                Py_INCREF(v);
-               np->ob_item[i] = v;
+               dest[i] = v;
        }
+       src = b->ob_item;
+       dest = np->ob_item + a->ob_size;
        for (i = 0; i < b->ob_size; i++) {
-               PyObject *v = b->ob_item[i];
+               PyObject *v = src[i];
                Py_INCREF(v);
-               np->ob_item[i + a->ob_size] = v;
+               dest[i] = v;
        }
        return (PyObject *)np;
 #undef b
@@ -383,7 +390,7 @@ tuplerepeat(PyTupleObject *a, int n)
        int i, j;
        int size;
        PyTupleObject *np;
-       PyObject **p;
+       PyObject **p, **items;
        if (n < 0)
                n = 0;
        if (a->ob_size == 0 || n == 1) {
@@ -403,9 +410,10 @@ tuplerepeat(PyTupleObject *a, int n)
        if (np == NULL)
                return NULL;
        p = np->ob_item;
+       items = a->ob_item;
        for (i = 0; i < n; i++) {
                for (j = 0; j < a->ob_size; j++) {
-                       *p = a->ob_item[j];
+                       *p = items[j];
                        Py_INCREF(*p);
                        p++;
                }
@@ -584,6 +592,7 @@ tuplesubscript(PyTupleObject* self, PyObject* item)
                int start, stop, step, slicelength, cur, i;
                PyObject* result;
                PyObject* it;
+               PyObject **src, **dest;
 
                if (PySlice_GetIndicesEx((PySliceObject*)item,
                                 PyTuple_GET_SIZE(self),
@@ -597,11 +606,13 @@ tuplesubscript(PyTupleObject* self, PyObject* item)
                else {
                        result = PyTuple_New(slicelength);
 
+                       src = self->ob_item;
+                       dest = ((PyTupleObject *)result)->ob_item;
                        for (cur = start, i = 0; i < slicelength; 
                             cur += step, i++) {
-                               it = PyTuple_GET_ITEM(self, cur);
+                               it = src[cur];
                                Py_INCREF(it);
-                               PyTuple_SET_ITEM(result, i, it);
+                               dest[i] = it;
                        }
                        
                        return result;