8000 bpo-43574: Dont overallocate list literals by chadnetzer · Pull Request #24954 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

bpo-43574: Dont overallocate list literals #24954

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Prev Previous commit
Next Next commit
Allow empty list append/insert to overallocate
The list_resize() helper is used by single-item list appends and
inserts, which normally would overallocate (to a capacity of 4) on the
first added element, and then again to 8 when the capacity is filled.
But if this over-allocation is postponed on the first added element, the
current expansion formula would then over-allocate to a capacity of 8 on
the second append/insertion.

List-literals of length 1 and 2 are not created with the list_extend()
function (which then calls list_resize()), but instead built directly as
capacity 1 or 2 lists with the BUILD_LIST opcode.  By excluding the
special case for list_resize() of empty lists when newsize is greater
than 1, its allows list append/insert to continue to over-allocate
without skipping capacity 4.
  • Loading branch information
chadnetzer committed Apr 4, 2021
commit 657d51fcb25d7653fff91c044fde3452b2bce056
7 changes: 5 additions & 2 deletions Objects/listobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,11 @@ list_resize(PyListObject *self, Py_ssize_t newsize)
return 0;
}

if (Py_SIZE(self) == 0 || newsize == 0) {
/* Don't overallocate for lists that start empty or are set to empty. */
if (newsize == 0 || (Py_SIZE(self) == 0 && newsize > 1)) {
/* Don't overallocate empty lists that are extended by more than 1
* element. This helps ensure that list-literals aren't
* over-allocated, but still allows it for empty-list append/insert.
*/
new_allocated = newsize;
}
else {
Expand Down
0