Given a tuple subclass defined by class mytuple(tuple): pass, memory allocation for mytuple objects currently goes through this code:
|
const size_t size = _PyObject_VAR_SIZE(type, nitems+1); |
|
/* note that we need to add one, for the sentinel */ |
That +1 in nitems+1 has a couple of consequences for mytuple instances; the first of those is a possible perfomance opportunity, while the second is a minor bug.
- on average (taking into account adjustments for alignment), we allocate 8 more bytes than necessary for each instance
sys.getsizeof consistently under-reports for these instances: the value reported is 8 bytes smaller than the value that was passed to PyObject_Malloc during object allocation
(Note: byte counts above assume a 64-bit platform.)
I did some hacky experimentation and was able to remove the +1 specifically for tuple subclasses with no apparent ill-effects. But the +1 definitely is needed for some varobjects (including PyHeapTypeObject, I think), and there may also be 3rd party extension code that either deliberately or inadvertently relies on it.
I haven't investigated whether there are other varobjects besides tuple subclasses for which the +1 could be removed.
Given a tuple subclass defined by
class mytuple(tuple): pass, memory allocation formytupleobjects currently goes through this code:cpython/Objects/typeobject.c
Lines 1292 to 1293 in e83f88a
That
+1innitems+1has a couple of consequences formytupleinstances; the first of those is a possible perfomance opportunity, while the second is a minor bug.sys.getsizeofconsistently under-reports for these instances: the value reported is 8 bytes smaller than the value that was passed toPyObject_Mallocduring object allocation(Note: byte counts above assume a 64-bit platform.)
I did some hacky experimentation and was able to remove the
+1specifically for tuple subclasses with no apparent ill-effects. But the+1definitely is needed for some varobjects (includingPyHeapTypeObject, I think), and there may also be 3rd party extension code that either deliberately or inadvertently relies on it.I haven't investigated whether there are other varobjects besides tuple subclasses for which the
+1could be removed.