Skip to content

Object allocation overallocates by 8 bytes for instances of tuple subclasses  #100659

@mdickinson

Description

@mdickinson

Given a tuple subclass defined by class mytuple(tuple): pass, memory allocation for mytuple objects currently goes through this code:

cpython/Objects/typeobject.c

Lines 1292 to 1293 in e83f88a

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    performancePerformance or resource usage
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions