mirror of https://github.com/python/cpython
Micro-optimize list index range checks (GH-9784)
This commit is contained in:
parent
1d26c72e6a
commit
f1aa8aed4a
|
@ -208,6 +208,19 @@ PyList_Size(PyObject *op)
|
|||
return Py_SIZE(op);
|
||||
}
|
||||
|
||||
static inline int
|
||||
valid_index(Py_ssize_t i, Py_ssize_t limit)
|
||||
{
|
||||
/* The cast to size_t lets us use just a single comparison
|
||||
to check whether i is in the range: 0 <= i < limit.
|
||||
|
||||
See: Section 14.2 "Bounds Checking" in the Agner Fog
|
||||
optimization manual found at:
|
||||
https://www.agner.org/optimize/optimizing_cpp.pdf
|
||||
*/
|
||||
return (size_t) i < (size_t) limit;
|
||||
}
|
||||
|
||||
static PyObject *indexerr = NULL;
|
||||
|
||||
PyObject *
|
||||
|
@ -217,7 +230,7 @@ PyList_GetItem(PyObject *op, Py_ssize_t i)
|
|||
PyErr_BadInternalCall();
|
||||
return NULL;
|
||||
}
|
||||
if (i < 0 || i >= Py_SIZE(op)) {
|
||||
if (!valid_index(i, Py_SIZE(op))) {
|
||||
if (indexerr == NULL) {
|
||||
indexerr = PyUnicode_FromString(
|
||||
"list index out of range");
|
||||
|
@ -240,7 +253,7 @@ PyList_SetItem(PyObject *op, Py_ssize_t i,
|
|||
PyErr_BadInternalCall();
|
||||
return -1;
|
||||
}
|
||||
if (i < 0 || i >= Py_SIZE(op)) {
|
||||
if (!valid_index(i, Py_SIZE(op))) {
|
||||
Py_XDECREF(newitem);
|
||||
PyErr_SetString(PyExc_IndexError,
|
||||
"list assignment index out of range");
|
||||
|
@ -426,7 +439,7 @@ list_contains(PyListObject *a, PyObject *el)
|
|||
static PyObject *
|
||||
list_item(PyListObject *a, Py_ssize_t i)
|
||||
{
|
||||
if (i < 0 || i >= Py_SIZE(a)) {
|
||||
if (!valid_index(i, Py_SIZE(a))) {
|
||||
if (indexerr == NULL) {
|
||||
indexerr = PyUnicode_FromString(
|
||||
"list index out of range");
|
||||
|
@ -749,7 +762,7 @@ list_inplace_repeat(PyListObject *self, Py_ssize_t n)
|
|||
static int
|
||||
list_ass_item(PyListObject *a, Py_ssize_t i, PyObject *v)
|
||||
{
|
||||
if (i < 0 || i >= Py_SIZE(a)) {
|
||||
if (!valid_index(i, Py_SIZE(a))) {
|
||||
PyErr_SetString(PyExc_IndexError,
|
||||
"list assignment index out of range");
|
||||
return -1;
|
||||
|
@ -996,7 +1009,7 @@ list_pop_impl(PyListObject *self, Py_ssize_t index)
|
|||
}
|
||||
if (index < 0)
|
||||
index += Py_SIZE(self);
|
||||
if (index < 0 || index >= Py_SIZE(self)) {
|
||||
if (!valid_index(index, Py_SIZE(self))) {
|
||||
PyErr_SetString(PyExc_IndexError, "pop index out of range");
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue