summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2004-03-09 08:04:33 (GMT)
committerRaymond Hettinger <python@rcn.com>2004-03-09 08:04:33 (GMT)
commitf889e10c198864ec5e14bb5f93d63f5b1ce21cc8 (patch)
treee2bd49a2c2f7eeeecafe2072a00eb658687b33e5
parent9168c70438a4f95099dc77377ceb11017bd1ff36 (diff)
downloadcpython-f889e10c198864ec5e14bb5f93d63f5b1ce21cc8.zip
cpython-f889e10c198864ec5e14bb5f93d63f5b1ce21cc8.tar.gz
cpython-f889e10c198864ec5e14bb5f93d63f5b1ce21cc8.tar.bz2
Optimize slice assignments.
* Replace sprintf message with a constant message string -- this error message ran on every invocation except straight deletions but it was only needed when the rhs was not iterable. The message was also out-of-date and did not reflect that iterable arguments were allowed. * For inner loops that do not make ref count adjustments, use memmove() for fast copying and better readability. * For inner loops that do make ref count adjustments, speed them up by factoring out the constant structure reference and using vitem[] instead.
-rw-r--r--Objects/listobject.c33
1 files changed, 17 insertions, 16 deletions
diff --git a/Objects/listobject.c b/Objects/listobject.c
index f5a9c7b..fd0dc70 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -460,6 +460,7 @@ list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v)
list. :-( */
PyObject **recycle, **p;
PyObject **item;
+ PyObject **vitem = NULL;
PyObject *v_as_SF = NULL; /* PySequence_Fast(v) */
int n; /* Size of replacement list */
int d; /* Change in size */
@@ -469,7 +470,6 @@ list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v)
if (v == NULL)
n = 0;
else {
- char msg[256];
if (a == b) {
/* Special case "a[i:j] = a" -- copy b first */
int ret;
@@ -480,15 +480,16 @@ list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v)
Py_DECREF(v);
return ret;
}
-
- PyOS_snprintf(msg, sizeof(msg),
- "must assign sequence"
- " (not \"%.200s\") to slice",
- v->ob_type->tp_name);
- v_as_SF = PySequence_Fast(v, msg);
+ v_as_SF = PySequence_Fast(v, "can only assign an iterable");
if(v_as_SF == NULL)
return -1;
n = PySequence_Fast_GET_SIZE(v_as_SF);
+ if (PyList_Check(v_as_SF))
+ vitem = ((PyListObject *)v_as_SF)->ob_item;
+ else {
+ assert (PyTuple_Check(v_as_SF));
+ vitem = ((PyTupleObject *)v_as_SF)->ob_item;
+ }
}
if (ilow < 0)
ilow = 0;
@@ -510,11 +511,11 @@ list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v)
else
p = recycle = NULL;
if (d <= 0) { /* Delete -d items; recycle ihigh-ilow items */
- for (k = ilow; k < ihigh; k++)
- *p++ = item[k];
+ memmove(p, &item[ilow], (ihigh - ilow)*sizeof(PyObject *));
+ p += ihigh - ilow;
if (d < 0) {
- for (/*k = ihigh*/; k < a->ob_size; k++)
- item[k+d] = item[k];
+ memmove(&item[ihigh+d], &item[ihigh],
+ (a->ob_size - ihigh)*sizeof(PyObject *));
list_resize(a, a->ob_size + d);
item = a->ob_item;
}
@@ -527,13 +528,13 @@ list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v)
return -1;
}
item = a->ob_item;
- for (k = s; --k >= ihigh; )
- item[k+d] = item[k];
- for (/*k = ihigh-1*/; k >= ilow; --k)
- *p++ = item[k];
+ memmove(&item[ihigh+d], &item[ihigh],
+ (s - ihigh)*sizeof(PyObject *));
+ memmove(p, &item[ilow], (ihigh - ilow)*sizeof(PyObject *));
+ p += ihigh - ilow;
}
for (k = 0; k < n; k++, ilow++) {
- PyObject *w = PySequence_Fast_GET_ITEM(v_as_SF, k);
+ PyObject *w = vitem[k];
Py_XINCREF(w);
item[ilow] = w;
}