在 Python 中准确测量对象大小 - Sys.GetSizeOf 不起作用 [英] Measure Object Size Accurately in Python - Sys.GetSizeOf not functioning

查看:14
本文介绍了在 Python 中准确测量对象大小 - Sys.GetSizeOf 不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图准确/明确地找到 Python 中两个不同类之间的大小差异.它们都是新的样式类,除了一个没有定义.我尝试了无数次测试来确定它们的大小差异,但最终它们的内存使用量总是相同的.

到目前为止,我已经尝试了 sys.GetSizeOf(obj) 和 heapy 的 heap() 函数,但没有任何积极的结果.测试代码如下:

导入系统从孔雀鱼进口 hpy类 test3(对象):def __init__(self):self.one = 1self.two = 两个变量"类 test4(对象):__slots__ = ('一', '二')def __init__(self):self.one = 1self.two = 两个变量"test3_obj = test3()打印Sizeof test3_obj",sys.getsizeof(test3_obj)test4_obj = test4()打印Sizeof test4_obj",sys.getsizeof(test4_obj)arr_test3 = []arr_test4 = []对于我在范围内(3000):arr_test3.append(test3())arr_test4.append(test4())h = hpy()打印 h.heap()

输出:

<块引用>

sizeof test3_obj 32大小 test4_obj 32一组 34717 个对象的分区.总大小 = 2589028 字节.索引计数 % 大小 % 累积 % 种类(类/类的字典)0 11896 34 765040 30 765040 301 3001 9 420140 16 1185180 46 __main__.test3 的字典2 5573 16 225240 9 1410420 54 元组3 348 1 167376 6 1577796 61 dict(无所有者)4 1567 5 106556 4 1684352 65 种.代码类型5 68 0 105136 4 1789488 69 模块字典6 183 1 97428 4 1886916 73 类型的字典7 3001 9 96032 4 1982948 77 __main__.test38 3001 9 96032 4 2078980 80 __main__.test49 203 1 90360 3 2169340 84型<99 行.输入例如_.more"查看.>

这都是 Python 2.6.0.我还尝试覆盖类的 sizeof 方法来尝试通过对各个 sizeofs 求和来确定大小,但没有产生任何不同的结果:

class test4(object):__slots__ = ('一', '二')def __init__(self):self.one = 1self.two = 两个变量"def __sizeof__(self):return super(test4, self).__sizeof__() + self.one.__sizeof__() + self.two.__sizeof__()

覆盖了 sizeof 方法的结果:

<块引用>

sizeof test3_obj 80大小 test4_obj 80

解决方案

sys.getsizeof 返回一个比人们想象的更专业、更没用的数字.事实上,如果将属性数增加到 6,则 test3_obj 仍为 32,但 test4_obj 会跳转到 48 个字节.这是因为 getsizeof 正在返回实现类型的 PyObject 结构的大小,对于 test3_obj 不包括保存属性的 dict,但对于 test4_obj,属性不存储在 dict 中,它们存储在插槽中,所以它们被计入大小.

但是使用 __slots__ 定义的类比没有定义的类占用更少的内存,正是因为没有 dict 来保存属性.

为什么要覆盖 __sizeof__?你真正想要完成什么?

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

解决方案

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?

这篇关于在 Python 中准确测量对象大小 - Sys.GetSizeOf 不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆