-
-
Notifications
You must be signed in to change notification settings - Fork 31.1k
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
Regression in overallocation for literal list initialization in v3.9+ #87740
Comments
In Python v3.9+ there was a regression in the amount of used memory for Example, in Python v3.8.x (and before):
whereas for v3.9 (and later):
However, this seems like an unintented regression, and is a side-effect of the
Prior to v3.9, the byte-code for making a list from a literal had the Ie. a minimal-change patch to restore the previous behavior (though with a diff --git a/Objects/listobject.c b/Objects/listobject.c - if (newsize == 0)
- new_allocated = 0;
+ /* Don't overallocate for lists that start empty or are set to empty. */
+ if (newsize == 0 || Py_SIZE(self) == 0)
+ new_allocated = newsize;
num_allocated_bytes = new_allocated * sizeof(PyObject *);
items = (PyObject **)PyMem_Realloc(self->ob_item, num_allocated_bytes);
if (items == NULL) { Relevant/related bugs/PRs: # Commit where over-allocation of list literals first appeared |
For bpo-43574, my initial plan was to change list_resize() so that it wouldn't However, the list_resize() helper is also used by list appends and inserts, as Therefore, my updated proposal handles this by changing the overallocation To understand why this updated proposed change won't also cause overallocation
Hence, the change to list_resize(), which is called by list_extend() but not And to show how the originally proposed change (no overallocation for
Note that the list-literal of length 1 isn't overallocated, and that However, with my originally proposed change, this overallocation behavior is Here was the overallocation behavior of my first proposal, when an empty list
This is unexpected and likely undesirable behavior, as lists being created Fixing this is fairly simple because of the special-casing for length 1 and 2 With this updated proposal, avoiding a change to the behavior of an empty list
So, with this variant on my original proposal, using the current compilation Just to document it, here are the functions in Objects/listobject.c that are ins1() # insert 1 element in list, including empty list.
app1() # append 1 element to list. Same impact as with ins1()
list_ass_slice() # can assign a sequence to a list slice, expanding list
list_inplace_repeat() # No impact, early exit for len == 0
list_extend() # Now used for list-literals of len > 2
list_pop() # No impact, same behavior for list becoming len == 0
list_ass_subscript() # No impact, list_resize() only called for deletion The list_ass_slice() case is changed by this update, for an empty list, as
and the behavior with my revised proposal for non-overallocation of
|
Relating issue: https://twitter.com/nedbat/status/1489233208713437190 |
I think this is no longer present in Python 3.11, thanks to #31816. py -3.9 -c "print(([1,2,3,4,5,6,7,8,9].__sizeof__() - [].__sizeof__())//8)"
12
py -3.10 -c "print(([1,2,3,4,5,6,7,8,9].__sizeof__() - [].__sizeof__())//8)"
12
py -3.11 -c "print(([1,2,3,4,5,6,7,8,9].__sizeof__() - [].__sizeof__())//8)"
9 Can this be closed? |
I backported #31816 to 3.10 branch. Close this issue for now. |
…31816) (cherry picked from commit 2153daf) This patch fixes gh-87740 too. Co-authored-by: Crowthebird <[email protected]>
This change introduced a regression. See #92914. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: