Reputation: 37
Why the size of the 2nd list decreased with the increase of the element 'XYZ'?, In the case of the tuple, it increased as expected.
import sys
l1 = [1,2,3,4, "Quant Tading", "Python"]
t1 = (1,2,3,4, "Quant Tading", "Python")
print(sys.getsizeof(l1)) #output 152
print(sys.getsizeof(t1)) #output 88
import sys
l1 = [1,2,3,4, "Quant Tading", "Python", "xyz"]
t1 = (1,2,3,4, "Quant Tading", "Python", "xyz")
print(sys.getsizeof(l1)) # why size decreased to 120?
print(sys.getsizeof(t1)) # output 96
Upvotes: 1
Views: 236
Reputation: 43103
This is a regression1 in Python 3.9 that has been fixed2 in Python 3.10 (3.10.5).
In Python v3.9+ there was a regression in the amount of used memory for list-literals, due to switching to using list_extend() to allocate memory for the new list to accomodate the literal elements. ...
Prior to v3.9, the byte-code for making a list from a literal had the "BUILD_LIST" opcode with an explicit length argument, allowing allocation of the exact amount of memory needed for the literal. As of v3.9, the LIST_EXTEND opcode is used, instead. I believe the simplest way of restoring the old behavior is to change list_extend() to not overallocate when the list being extended currently has 0 elements.
Python 3.8 and Python 3.10:
import sys
l1 = [1,2,3,4, "Quant Tading", "Python"]
t1 = (1,2,3,4, "Quant Tading", "Python")
print(sys.getsizeof(l1)) # output 104
print(sys.getsizeof(t1)) # output 88
import sys
l2 = [1,2,3,4, "Quant Tading", "Python", "xyz"]
t2 = (1,2,3,4, "Quant Tading", "Python", "xyz")
print(sys.getsizeof(l2)) # output 112
print(sys.getsizeof(t2)) # output 96
You can verify on https://www.python.org/shell/ (Python 3.10.5 when this answer was posted).
[1] Regression in overallocation for literal list initialization in v3.9+ (issues/87740)
[2] bpo-39829: Optimize __len__() being called twice in the list() constructor (pull/31816)
Upvotes: 2