diff options
author | Raymond Hettinger <python@rcn.com> | 2004-03-09 13:05:22 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2004-03-09 13:05:22 (GMT) |
commit | a6366fe085dba6b47ff33a472a5371c4573a8c30 (patch) | |
tree | 35bf9fe9d94fcf7642de0de4aafaf98f80f5e307 | |
parent | f889e10c198864ec5e14bb5f93d63f5b1ce21cc8 (diff) | |
download | cpython-a6366fe085dba6b47ff33a472a5371c4573a8c30.zip cpython-a6366fe085dba6b47ff33a472a5371c4573a8c30.tar.gz cpython-a6366fe085dba6b47ff33a472a5371c4573a8c30.tar.bz2 |
Optimize inner loops for subscript, repeat, and concat.
-rw-r--r-- | Objects/listobject.c | 66 | ||||
-rw-r--r-- | Objects/tupleobject.c | 29 |
2 files changed, 59 insertions, 36 deletions
diff --git a/Objects/listobject.c b/Objects/listobject.c index fd0dc70..47f4a37 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -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++) { diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index eaf3c88..2d49448 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -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; |