mirror of
https://github.com/python/cpython.git
synced 2025-11-07 21:29:26 +00:00
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.
This commit is contained in:
parent
9168c70438
commit
f889e10c19
1 changed files with 17 additions and 16 deletions
|
|
@ -460,6 +460,7 @@ list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v)
|
||||||
list. :-( */
|
list. :-( */
|
||||||
PyObject **recycle, **p;
|
PyObject **recycle, **p;
|
||||||
PyObject **item;
|
PyObject **item;
|
||||||
|
PyObject **vitem = NULL;
|
||||||
PyObject *v_as_SF = NULL; /* PySequence_Fast(v) */
|
PyObject *v_as_SF = NULL; /* PySequence_Fast(v) */
|
||||||
int n; /* Size of replacement list */
|
int n; /* Size of replacement list */
|
||||||
int d; /* Change in size */
|
int d; /* Change in size */
|
||||||
|
|
@ -469,7 +470,6 @@ list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v)
|
||||||
if (v == NULL)
|
if (v == NULL)
|
||||||
n = 0;
|
n = 0;
|
||||||
else {
|
else {
|
||||||
char msg[256];
|
|
||||||
if (a == b) {
|
if (a == b) {
|
||||||
/* Special case "a[i:j] = a" -- copy b first */
|
/* Special case "a[i:j] = a" -- copy b first */
|
||||||
int ret;
|
int ret;
|
||||||
|
|
@ -480,15 +480,16 @@ list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v)
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
v_as_SF = PySequence_Fast(v, "can only assign an iterable");
|
||||||
PyOS_snprintf(msg, sizeof(msg),
|
|
||||||
"must assign sequence"
|
|
||||||
" (not \"%.200s\") to slice",
|
|
||||||
v->ob_type->tp_name);
|
|
||||||
v_as_SF = PySequence_Fast(v, msg);
|
|
||||||
if(v_as_SF == NULL)
|
if(v_as_SF == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
n = PySequence_Fast_GET_SIZE(v_as_SF);
|
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)
|
if (ilow < 0)
|
||||||
ilow = 0;
|
ilow = 0;
|
||||||
|
|
@ -510,11 +511,11 @@ list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v)
|
||||||
else
|
else
|
||||||
p = recycle = NULL;
|
p = recycle = NULL;
|
||||||
if (d <= 0) { /* Delete -d items; recycle ihigh-ilow items */
|
if (d <= 0) { /* Delete -d items; recycle ihigh-ilow items */
|
||||||
for (k = ilow; k < ihigh; k++)
|
memmove(p, &item[ilow], (ihigh - ilow)*sizeof(PyObject *));
|
||||||
*p++ = item[k];
|
p += ihigh - ilow;
|
||||||
if (d < 0) {
|
if (d < 0) {
|
||||||
for (/*k = ihigh*/; k < a->ob_size; k++)
|
memmove(&item[ihigh+d], &item[ihigh],
|
||||||
item[k+d] = item[k];
|
(a->ob_size - ihigh)*sizeof(PyObject *));
|
||||||
list_resize(a, a->ob_size + d);
|
list_resize(a, a->ob_size + d);
|
||||||
item = a->ob_item;
|
item = a->ob_item;
|
||||||
}
|
}
|
||||||
|
|
@ -527,13 +528,13 @@ list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
item = a->ob_item;
|
item = a->ob_item;
|
||||||
for (k = s; --k >= ihigh; )
|
memmove(&item[ihigh+d], &item[ihigh],
|
||||||
item[k+d] = item[k];
|
(s - ihigh)*sizeof(PyObject *));
|
||||||
for (/*k = ihigh-1*/; k >= ilow; --k)
|
memmove(p, &item[ilow], (ihigh - ilow)*sizeof(PyObject *));
|
||||||
*p++ = item[k];
|
p += ihigh - ilow;
|
||||||
}
|
}
|
||||||
for (k = 0; k < n; k++, 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);
|
Py_XINCREF(w);
|
||||||
item[ilow] = w;
|
item[ilow] = w;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue