Python程序使用太多内存

时间:2011-11-14 03:38:17

标签: python optimization memory 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

myobj是一个具有大约20个真/假值和20个数值的类(所有这些都可以存储在2个字节中)。

我有一个256 * 256的数组。我真的不明白为什么他们消耗35或70 MB的内存。如果可能的话,我想把它降到10 MB以下。

对象内的大部分数据被组织成字典以便于访问。字典本身并没有改变,而且毫无意义。它们会造成很大的开销吗?

使用按位运算符将所有数据打包成1个数字是否有益?我应该能够以32或64字节存储对象的整个数据。我希望编译器会像其他语言一样自动执行此类操作,但它似乎正好相反。

除了使用装饰器之外,该类继承了内置类型对象。这会导致很多开销吗?

还好奇“dict(没有所有者)”是什么意思,以及它消耗了另一半的记忆。

编辑:sys.getsizeof(myobj.Container)确实报告了450个字节!疯了吧。我只使用字典,因为我需要根据索引访问数据。就我而言,编译器应该摆脱结构并直接访问值。有没有更好的方法呢? (我不认为列表是答案)

1 个答案:

答案 0 :(得分:6)

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())或类似的。即使这不准确,因为除了基础对象之外它不包括任何东西。它没有考虑包含属性的字典。它只会报告报告中第三行的大小。