use*_*037 4 python memory optimization profiling
我从Heapy得到了这些结果,但目前还不清楚它们究竟是什么意思.
Index Count % Size % Cumulative % Kind (class / dict of class)
0 262539 59 36961284 48 36961284 48 dict (no owner)
1 65536 15 34340864 45 71302148 93 dict of myobj.Container
2 65536 15 2097152 3 73399300 96 myobj.Container
Run Code Online (Sandbox Code Playgroud)
myobj是一个具有大约20个真/假值和20个数值的类(所有这些都可以存储在2个字节中).
我有一个256*256的数组.我真的不明白为什么他们消耗35或70 MB的内存.如果可能的话,我想把它降到10 MB以下.
对象内的大部分数据被组织成字典以便于访问.字典本身并没有改变,而且毫无意义.它们会导致很多开销吗?
使用按位运算符将所有数据打包成1个数字是否有益?我应该能够以32或64字节存储对象的整个数据.我希望编译器会像其他语言一样自动执行此类操作,但它似乎正好相反.
除了使用装饰器之外,该类无缘无故地继承了内置类型对象.这会导致很多开销吗?
同样好奇"dict(没有所有者)"意味着什么以及它消耗了另一半的内存.
编辑:sys.getsizeof(myobj.Container)确实报告了450个字节!疯了吧.我只使用字典,因为我需要根据索引访问数据.就我而言,编译器应该摆脱结构并直接访问值.有没有更好的方法呢?(我不认为列表是答案)
Python并没有消除像这样的结构的开销.抱歉.其动态特性使这种编译器优化变得困难.但后来我不知道任何语言会消除因保留字典而引入的开销.
dict(没有所有者)可能包含您在对象中创建的所有词典.它们被标记为无所有者,因为它们不是对象实例的字典.
你可以做什么:
使用__slots__,如果添加__slots__ = ('the','names','of','fields')为类属性,python将使用更高效的类实现.它将摆脱用于保存属性的字典.
如果您的词典可以被重写以使用可以改善情况的列表.列表比字典更有效.
为了获得最佳效率,您应该重新设计系统以使用numpy数组.类中的每个属性都将成为256*256大小的数组.在这种情况下,每个元素将在空间上非常有效地存储.
或者,您可以签出PyPy.它提供了带有JIT的python的替代实现以及可能有用的各种时间/空间优化.
sys.getsizeof不报告您认为其报告的内容.sys.getsizeof(myobj.Container)报告类对象的大小,而不是实际Container对象的大小.你想要sys.getsizeof(myobj.Container())或类似.即使这不准确,因为除了基础对象之外它不包括任何东西.它没有考虑包含属性的字典.它只会报告报告中第三行的大小.