Commit a6366fe0 authored by Raymond Hettinger's avatar Raymond Hettinger

Optimize inner loops for subscript, repeat, and concat.

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