为什么 pstats.print_callers() 会忽略限制参数?
Why is pstats.print_callers() ignores the restriction argument?
我正在尝试使用 cProfile
分析我的 python 脚本并使用 pstats
显示结果。特别是,我正在尝试使用 pstats
函数 p.sort_stats('time').print_callers(20)
按时间仅打印前 20 个函数,如 documentation 中所述。
我希望只获得前 20 个结果(分析的函数及其调用函数按时间排序),相反,我得到一个看似未经过滤的超过 1000 个函数的列表,完全饱和了我的终端(因此我估计超过1000 个函数)。
为什么我的限制参数(即 20
)被 print_callers()
忽略,我该如何解决这个问题?
我尝试查找答案,但找不到。我尝试创建一个最小的可重现示例,但是当我这样做时,我无法重现问题(即它工作正常)。
我的分析代码是:
import cProfile
import pstats
if __name__ == '__main__':
cProfile.run('main()', 'mystats')
p = pstats.Stats('mystats')
p.sort_stats('time').print_callers(20)
我尽量避免 post 我的完整代码,所以如果其他人以前遇到过这个问题,并且可以在没有看到我的完整代码的情况下回答,那就太好了。
非常感谢您。
编辑 1:
部分输出:
Ordered by: internal time
List reduced from 1430 to 1 due to restriction <1>
Function was called by...
ncalls tottime cumtime
{built-in method builtins.isinstance} <- 2237 0.000 0.000 <frozen importlib._bootstrap>:997(_handle_fromlist)
9 0.000 0.000 <frozen importlib._bootstrap_external>:485(_compile_bytecode)
44 0.000 0.000 <frozen importlib._bootstrap_external>:1117(_get_spec)
4872 0.001 0.001 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\_strptime.py:321(_strptime)
5 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\abc.py:196(__subclasscheck__)
26 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\calendar.py:58(__getitem__)
14 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\calendar.py:77(__getitem__)
2 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\distutils\version.py:331(_cmp)
20 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\enum.py:797(__or__)
362 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\enum.py:803(__and__)
1 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\inspect.py:73(isclass)
30 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\json\encoder.py:182(encode)
2 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\ntpath.py:34(_get_bothseps)
1 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\ntpath.py:75(join)
4 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\ntpath.py:122(splitdrive)
3 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\ntpath.py:309(expanduser)
4 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\os.py:728(check_str)
44 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\re.py:249(escape)
4 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\re.py:286(_compile)
609 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\site-packages\dateutil\parser\_parser.py:62(__init__)
1222 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\core\_methods.py:48(_count_reduce_items)
1222 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\core\_methods.py:58(_mean)
1 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\core\arrayprint.py:834(__init__)
1393 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\core\fromnumeric.py:1583(ravel)
1239 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\core\fromnumeric.py:1966(sum)
...
我想通了。
像往常一样,Python 库没有错误,而是我误解了函数调用的输出。
我在这里详细说明它作为一个答案,以防万一它可以帮助任何人在未来消除这个误解。
当我问这个问题时,我不明白为什么 p.print_callers(20)
打印到终端超过一千行,即使我将它限制在前 20 个函数调用(按时间)。
实际发生的情况是,我限制打印前 20 个 "most time consuming functions",将列表限制为前 20 个函数,但随后打印调用 each 的所有函数的列表前 20 个函数中的 .
由于前 20 个函数中的每一个都被(平均)大约 100 个不同的函数调用,因此每个顶级函数都有大约 100 行与之相关联。所以 20*100=2000,所以 p.print_callers(20)
打印了超过 1000 行并使我的终端饱和。
我希望这可以节省一些时间和调试麻烦:)
我正在尝试使用 cProfile
分析我的 python 脚本并使用 pstats
显示结果。特别是,我正在尝试使用 pstats
函数 p.sort_stats('time').print_callers(20)
按时间仅打印前 20 个函数,如 documentation 中所述。
我希望只获得前 20 个结果(分析的函数及其调用函数按时间排序),相反,我得到一个看似未经过滤的超过 1000 个函数的列表,完全饱和了我的终端(因此我估计超过1000 个函数)。
为什么我的限制参数(即 20
)被 print_callers()
忽略,我该如何解决这个问题?
我尝试查找答案,但找不到。我尝试创建一个最小的可重现示例,但是当我这样做时,我无法重现问题(即它工作正常)。
我的分析代码是:
import cProfile
import pstats
if __name__ == '__main__':
cProfile.run('main()', 'mystats')
p = pstats.Stats('mystats')
p.sort_stats('time').print_callers(20)
我尽量避免 post 我的完整代码,所以如果其他人以前遇到过这个问题,并且可以在没有看到我的完整代码的情况下回答,那就太好了。
非常感谢您。
编辑 1: 部分输出:
Ordered by: internal time
List reduced from 1430 to 1 due to restriction <1>
Function was called by...
ncalls tottime cumtime
{built-in method builtins.isinstance} <- 2237 0.000 0.000 <frozen importlib._bootstrap>:997(_handle_fromlist)
9 0.000 0.000 <frozen importlib._bootstrap_external>:485(_compile_bytecode)
44 0.000 0.000 <frozen importlib._bootstrap_external>:1117(_get_spec)
4872 0.001 0.001 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\_strptime.py:321(_strptime)
5 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\abc.py:196(__subclasscheck__)
26 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\calendar.py:58(__getitem__)
14 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\calendar.py:77(__getitem__)
2 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\distutils\version.py:331(_cmp)
20 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\enum.py:797(__or__)
362 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\enum.py:803(__and__)
1 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\inspect.py:73(isclass)
30 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\json\encoder.py:182(encode)
2 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\ntpath.py:34(_get_bothseps)
1 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\ntpath.py:75(join)
4 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\ntpath.py:122(splitdrive)
3 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\ntpath.py:309(expanduser)
4 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\os.py:728(check_str)
44 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\re.py:249(escape)
4 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\re.py:286(_compile)
609 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\site-packages\dateutil\parser\_parser.py:62(__init__)
1222 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\core\_methods.py:48(_count_reduce_items)
1222 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\core\_methods.py:58(_mean)
1 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\core\arrayprint.py:834(__init__)
1393 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\core\fromnumeric.py:1583(ravel)
1239 0.000 0.000 C:\Users\rafael.natan\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\core\fromnumeric.py:1966(sum)
...
我想通了。 像往常一样,Python 库没有错误,而是我误解了函数调用的输出。
我在这里详细说明它作为一个答案,以防万一它可以帮助任何人在未来消除这个误解。
当我问这个问题时,我不明白为什么 p.print_callers(20)
打印到终端超过一千行,即使我将它限制在前 20 个函数调用(按时间)。
实际发生的情况是,我限制打印前 20 个 "most time consuming functions",将列表限制为前 20 个函数,但随后打印调用 each 的所有函数的列表前 20 个函数中的 .
由于前 20 个函数中的每一个都被(平均)大约 100 个不同的函数调用,因此每个顶级函数都有大约 100 行与之相关联。所以 20*100=2000,所以 p.print_callers(20)
打印了超过 1000 行并使我的终端饱和。
我希望这可以节省一些时间和调试麻烦:)