gh-94603: micro optimize list.pop (gh-94604)

This commit is contained in:
Pieter Eendebak 2022-12-27 11:55:54 +01:00 committed by GitHub
parent ce39aaffee
commit b3da698952
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 12 deletions

View File

@ -0,0 +1 @@
Improve performance of ``list.pop`` for small lists.

View File

@ -1022,21 +1022,29 @@ list_pop_impl(PyListObject *self, Py_ssize_t index)
PyErr_SetString(PyExc_IndexError, "pop index out of range"); PyErr_SetString(PyExc_IndexError, "pop index out of range");
return NULL; return NULL;
} }
v = self->ob_item[index];
if (index == Py_SIZE(self) - 1) { PyObject **items = self->ob_item;
status = list_resize(self, Py_SIZE(self) - 1); v = items[index];
if (status >= 0) const Py_ssize_t size_after_pop = Py_SIZE(self) - 1;
return v; /* and v now owns the reference the list had */ if (size_after_pop == 0) {
else Py_INCREF(v);
return NULL; status = _list_clear(self);
} }
Py_INCREF(v); else {
status = list_ass_slice(self, index, index+1, (PyObject *)NULL); if ((size_after_pop - index) > 0) {
if (status < 0) { memmove(&items[index], &items[index+1], (size_after_pop - index) * sizeof(PyObject *));
Py_DECREF(v); }
status = list_resize(self, size_after_pop);
}
if (status >= 0) {
return v; // and v now owns the reference the list had
}
else {
// list resize failed, need to restore
memmove(&items[index+1], &items[index], (size_after_pop - index)* sizeof(PyObject *));
items[index] = v;
return NULL; return NULL;
} }
return v;
} }
/* Reverse a slice of a list in place, from lo up to (exclusive) hi. */ /* Reverse a slice of a list in place, from lo up to (exclusive) hi. */