Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
655 views
in Technique[技术] by (71.8m points)

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

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 slots defined. I have tried numerous tests to determine their size difference, but they always end up being identical in memory usage.

So far I have tried sys.GetSizeOf(obj) and heapy's heap() function, with no positive results. Test code is below:

import sys
from guppy import hpy

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"

test3_obj = test3()
print "Sizeof test3_obj", sys.getsizeof(test3_obj)

test4_obj = test4()
print "Sizeof test4_obj", sys.getsizeof(test4_obj)

arr_test3 = []
arr_test4 = []

for i in range(3000):
    arr_test3.append(test3())
    arr_test4.append(test4())

h = hpy()
print h.heap()

Output:

Sizeof test3_obj 32
Sizeof test4_obj 32

Partition of a set of 34717 objects. Total size = 2589028 bytes.
 Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
     0  11896  34   765040  30    765040  30 str
     1   3001   9   420140  16   1185180  46 dict of __main__.test3
     2   5573  16   225240   9   1410420  54 tuple
     3    348   1   167376   6   1577796  61 dict (no owner)
     4   1567   5   106556   4   1684352  65 types.CodeType
     5     68   0   105136   4   1789488  69 dict of module
     6    183   1    97428   4   1886916  73 dict of type
     7   3001   9    96032   4   1982948  77 __main__.test3
     8   3001   9    96032   4   2078980  80 __main__.test4
     9    203   1    90360   3   2169340  84 type
<99 more rows. Type e.g. '_.more' to view.>

This is all with Python 2.6.0. I also attempted to override the class's sizeof methods to try determine the size by summing the individual sizeofs but that didn't yield any different results:

class test4(object):
    __slots__ = ('one', 'two')
    def __init__(self):
        self.one = 1
        self.two = "two variable"
    def __sizeof__(self):
        return super(test4, self).__sizeof__() + self.one.__sizeof__() + self.two.__sizeof__()

Results with the sizeof method overridden:

Sizeof test3_obj 80
Sizeof test4_obj 80
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

sys.getsizeof returns a number which is more specialized and less useful than people think. In fact, if you increase the number of attributes to six, your test3_obj remains at 32, but test4_obj jumps to 48 bytes. This is because getsizeof is returning the size of the PyObject structure implementing the type, which for test3_obj doesn't include the dict holding the attributes, but for test4_obj, the attributes aren't stored in a dict, they are stored in slots, so they are accounted for in the size.

But a class defined with __slots__ takes less memory than a class without, precisely because there is no dict to hold the attributes.

Why override __sizeof__? What are you really trying to accomplish?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...