Python 性能分析 - runsnakerun 输出中的列是什么意思?
这可能很明显,但我想确认一下我对runsnakerun中的各个列的理解。
名称、调用次数、递归调用次数、本地、每次调用、累计、每次调用、文件、行、目录
以下是我认为我理解的一些内容:
名称 - 被调用的函数名称
- 调用次数 - 是指调用的次数吗?
- 文件 - 存放这个函数的文件
- 行 - 函数在文件中的定义行
- 目录 - 存放函数定义的文件所在的目录
我不太确定的其他几个是:
- 递归调用次数
- 本地
- 每次调用
- 累计
- 每次调用
谢谢
2 个回答
这是我对这些内容的理解:
RCalls
表示递归调用的次数Local
表示在本地执行上花费的总时间(没有调用其他方法)/Call
表示每次调用的本地时间Cum
表示总的累积时间/Call
表示每次调用的累积时间
最好的方式是通过一个例子来说明——假设你有一个程序(存储在profileme.py中,为了清晰起见,分成了几部分):
def topfunction():
tinyfunction()
for i in range(100000):
manytinyfunction()
Calls很简单——就是这个函数被直接调用了多少次。当然,当你选择左侧的项目时,这些数字会变化,反映出被选中的函数调用了这个函数多少次。比如,manytinyfunction
会被调用100,000次,所以calls就是100,000。而tinyfunction
只会被调用一次,所以它的calls就是1。
for i in range(10):
recursive(100)
rcalls和calls类似,但它还包括在执行一个调用时发生的其他调用。注意recursive
的calls只有10,但rcalls是1010(下面会解释,它会自己调用n次,如果它的参数是n)。
alllocal()
allcumulative()
同样,local包括在函数内部花费的所有时间,不算调用其他函数的时间。在这里,alllocal
的值很大,但allcumulative
没有值,因为它把工作转给了subfunction
。
def tinyfunction():
pass
def manytinyfunction():
pass
/Call next to the local只是把上面的local值按调用次数分解,所以manytinyfunction
整体花费的时间很少,但在local /call中是一个非常非常小的数字,因为每次调用的成本真的很低。
def alllocal():
for i in range(1000):
for j in range(1000):
for k in range(1000):
pass
对于alllocal
,/call的值会很大,无论是local还是cumulative,因为这个函数的开销很大,而所有的开销都是local的。
def allcumulative():
for i in range(1000):
subfunction()
def subfunction():
for j in range(1000):
for k in range(1000):
pass
/Call next to cumulative和local的/call是一样的,只不过它像cumulative本身一样,包含了从这个函数调用出去的所有调用的完整成本。所以allcumulative
的local /call数字很小,但alllocal
的数字很大。而cumulative /call在这两种情况下是一样的。
def recursive(n):
if n > 0:
return recursive(n-1)
else:
return 0
这里提供了recursive
的定义以供参考。
if __name__=="__main__":
topfunction()
在对其进行性能分析并运行runsnake后:
python -m cProfile -o profileme.out profileme.py
runsnake profileme.out
注意到alllocal
在local和cumulative上都有很大的值,而allcumulative
则明显不同。注意recursive
在两列中是一样的——对自己调用的次数是被计算在内的。
底部的Callees按钮可以让你找出被选中的函数调用了哪些其他函数,而Callers则可以让你找出是谁在调用这个选中的函数。