python - 为什么 pstats.print_callers() 忽略限制参数?

标签 python profile cprofile pstats

我正在尝试使用 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)

我试图避免发布我的完整代码,所以如果其他人以前遇到过这个问题,并且可以在不看到我的完整代码的情况下回答,那就太好了。

提前非常感谢您。

编辑 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 个“最耗时的函数”,将列表限制为前 20 个函数,但随后打印调用每个顶部函数的所有函数的列表二十个功能。

由于前 20 个函数中的每一个(平均)被大约 100 个不同的函数调用,因此每个顶级函数都有大约 100 行与之关联。所以 20*100=2000,所以 p.print_callers(20) 打印了 1000 多行,并使我的终端饱和。

我希望这可以节省一些时间和调试头痛:)

关于python - 为什么 pstats.print_callers() 忽略限制参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58882338/

相关文章:

python - 长时间运行的 CPU 密集型 python 脚本被调度程序发送到 sleep 状态

Facebook 个人资料图片显示为 Http : on secure website expected Https:

performance - chrome中的javascript执行速度慢,分析器产生 "(program)"

python - cProfile 没有属性 runctx

python - 在 Linux 上升级 pip 时出错

Python-Child 类触发父类

python - 为什么 cProfile 模块不适用于 unittest?

numpy - 使用 cProfile 分析 numpy 没有给出有用的结果

python - 解压后系统使用大量内存

windows - 在 Windows 7 中设置信息亭模式的建议