diff options
author | Raymond Hettinger <python@rcn.com> | 2004-03-09 08:04:33 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2004-03-09 08:04:33 (GMT) |
commit | f889e10c198864ec5e14bb5f93d63f5b1ce21cc8 (patch) | |
tree | e2bd49a2c2f7eeeecafe2072a00eb658687b33e5 | |
parent | 9168c70438a4f95099dc77377ceb11017bd1ff36 (diff) | |
download | cpython-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.c | 33 |
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; } |