Measure Object Size Accurately in Python - Sys.GetSizeOf not functioning

前端 未结 6 1983
一向
一向 2020-11-30 12:31

I am trying to accurately/definitively find the size differences between two different classes in Python. They are both new style classes, save for one not having sl

6条回答
  •  北荒
    北荒 (楼主)
    2020-11-30 13:21

    The following function has been tested in Python 3.6, 64bit system. It has been very useful to me. (I picked it up off the internet and tweaked it to my style, and added the use of 'slots' feature. I am unable to find the original source again.)

    def getSize(obj, seen: Optional[Set[int]] = None) -> int:
      """Recursively finds size of objects. Needs: import sys """
      seen = set() if seen is None else seen
    
      if id(obj) in seen: return 0  # to handle self-referential objects
      seen.add(id(obj))
    
      size = sys.getsizeof(obj, 0) # pypy3 always returns default (necessary)
      if isinstance(obj, dict):
        size += sum(getSize(v, seen) + getSize(k, seen) for k, v in obj.items())
      elif hasattr(obj, '__dict__'):
        size += getSize(obj.__dict__, seen)
      elif hasattr(obj, '__slots__'): # in case slots are in use
        slotList = [getattr(C, "__slots__", []) for C in obj.__class__.__mro__]
        slotList = [[slot] if isinstance(slot, str) else slot for slot in slotList]
        size += sum(getSize(getattr(obj, a, None), seen) for slot in slotList for a in slot)
      elif hasattr(obj, '__iter__') and not isinstance(obj, (str, bytes, bytearray)):
        size += sum(getSize(i, seen) for i in obj)
      return size
    

    Now for the objects of the following classes,

    class test3(object):
        def __init__(self):
            self.one = 1
            self.two = "two variable"
    
    class test4(object):
        __slots__ = ('one', 'two')
        def __init__(self):
            self.one = 1
            self.two = "two variable"
    

    the following results are obtained,

    In [21]: t3 = test3()
    
    In [22]: getSize(t3)
    Out[22]: 361
    
    In [23]: t4 = test4()
    
    In [25]: getSize(t4)
    Out[25]: 145
    

    Feedbacks to improve the function are most welcome.

提交回复
热议问题