关于Python代码的一般性问题。 如何在内存使用方面最有效地找到Python代码中最糟糕的部分?
参见例如这个小例子
def my_func():
a = [1] * (12 ** 4)
return a
def my_func2():
b = [2] * (10 ** 7)
return b
if __name__ == '__main__':
a1 = my_func()
a2 = my_func2()
我怎样才能以自动方式告诉a2比a1大得多?
我怎样才能 - 仍然自动化 - 将其重新导向my_func1()
和my_func2()
?
对于C / C ++代码,我会使用valgrind --tool=massif
,它可以直接找到关于内存使用的重量级 - 但对于Python我需要你的帮助。
Meliae似乎给出了一些答案,但不及Massif对C / C ++的好处。
答案 0 :(得分:0)
locals()(resp.globals())返回一个包含所有本地(resp。全局)活动对象的字典。您可以像这样使用它们:
import sys
sizes = dict((obj, sys.getsizeof(eval(obj))) for obj in locals().keys())
缺点是它不会知道没有完全实现__getsizeof__
的对象,如Numpy数组或引用。例如,如果你这样做:
print sys.getsizeof(a2)
sys.getsizeof(a1)
a2.append(a1)
print sys.getsizeof(a2)
输出将是:
40000036
82980
45000064 ---> The list is 60 times bigger!
当然,只是删除a1不会释放它的82 k,因为a1中仍然有一个引用。但我们可以让它变得更奇怪:
a2 = my_func2()
print sys.getsizeof(a2)
a2.append(a2)
print sys.getsizeof(a2)
输出看起来很奇怪:
40000036
45000064
其他工具可能会对此实现变通方法,并搜索引用树,但Python中完整内存分析的一般问题仍未解决。当对象通过C API在参考计数器的范围之外存储数据时,这会变得更糟,例如,与Numpy数组一起发生。
也就是说,对于大多数实际情况,有些工具“足够好”。与引用的链接一样,Heapy是一个非常好的选择。