我正在玩这个memory_profiler
包(从 pip 下载),更具体地说,通过首先创建一个临时列表与循环通过“迭代器列表”来查看循环通过列表的内存效率。
这是我不久前遇到的一个问题,我想对我的解决方案进行基准测试。问题是我需要将列表中的每个元素与同一列表中的下一个元素进行比较,直到所有元素都被“处理”。所以我想这将是一个 O(n^2) 解决方案(如果选择最简单的解决方案,对于列表中的每个元素,循环遍历列表)。
无论如何,下面的三个函数都在做同样的事情(或多或少);循环使用自身偏移压缩的列表。
import cProfile
@profile
def zips():
li = range(1,20000000)
for tup in zip(li,li[1:]):
pass
del li
@profile
def izips():
from itertools import izip
li = range(1,20000000)
for tup in izip(li,li[1:]):
pass
del li
@profile
def izips2():
from itertools import izip
li = range(1,20000000)
for tup in izip(li,li[1:]):
del tup
del li
if __name__ == '__main__':
zips()
# izips()
# izips2()
(对我来说)令人惊讶的部分是内存使用情况,首先我运行 zips() 函数,虽然我认为我确实清理了,但最终我仍然有大约 1.5 GB 的内存:
ipython -m memory_profiler python_profiling.py
Filename: python_profiling.py
Line # Mem usage Increment Line Contents
================================================
10 @profile
11 27.730 MB 0.000 MB def zips():
12 649.301 MB 621.570 MB li = range(1,20000000)
13 3257.605 MB 2608.305 MB for tup in zip(li,li[1:]):
14 1702.504 MB -1555.102 MB pass
15 1549.914 MB -152.590 MB del li
然后我关闭解释器实例并重新打开它以运行下一个测试,即 izips() 函数:
ipython -m memory_profiler python_profiling.py
Filename: python_profiling.py
Line # Mem usage Increment Line Contents
================================================
17 @profile
18 27.449 MB 0.000 MB def izips():
19 27.449 MB 0.000 MB from itertools import izip
20 649.051 MB 621.602 MB li = range(1,20000000)
21 1899.512 MB 1250.461 MB for tup in izip(li,li[1:]):
22 1746.922 MB -152.590 MB pass
23 1594.332 MB -152.590 MB del li
最后我运行了一个测试(在中间重新启动解释器之后再次),我试图在 for 循环中显式删除元组以确保它的内存将被释放(也许我的想法不正确? )。事实证明这并没有什么不同,所以我猜要么我没有提示 GC,要么这不是我的内存开销的来源。
ipython -m memory_profiler python_profiling.py
Filename: python_profiling.py
Line # Mem usage Increment Line Contents
================================================
25 @profile
26 20.109 MB 0.000 MB def izips2():
27 20.109 MB 0.000 MB from itertools import izip
28 641.676 MB 621.566 MB li = range(1,20000000)
29 1816.953 MB 1175.277 MB for tup in izip(li,li[1:]):
30 1664.387 MB -152.566 MB del tup
31 1511.797 MB -152.590 MB del li
底线:我认为 for 循环本身的开销很小,因此,我期待的只是多一点点 ~620.000 MB(存储列表所需的内存),但看起来我有 ~2内存中大小为 20.000.000 的列表 + 更多开销。谁能帮我解释一下所有这些内存的用途?(以及在每次运行结束时占用了 ~1.5 GB 的空间是什么?)