这类似于Profiling in Python: Who called the function? ,但有所不同。。我有一个使用cProfile进行分析的python函数。在我的首次运行中,统计数据显示,它大部分时间都花在%(FooterContent)
的{{1}}中;
好的,我在系统上找到了get_loc()
文件,并在datetimes.py
的顶部临时添加了datetimes.py
和import pdb
,然后随机使用了调试器命令{{1} }多次,并且pdb.set_trace()
之间的随机数为get_loc()
。这告诉我,根据我的随机样本,几乎所有where
的数千次调用最终都来自我自己代码中的同一位置。我修改了该代码以大大减少调用次数。太好了!
接下来,我现在看到在对continue
的超过66,000 个调用中花费了大量时间;问题是我找不到实现堆栈跟踪的源代码,无法找出正在调用的where
。 (根据我对Python的有限知识,我正在猜测,实际上get_loc()
是直接或通过共享对象链接到Python解释器的C代码)。无论如何,我找不到所谓的builtins.isinstance()
。我尝试了在Profiling in Python: Who called the function? 的答案中也发现的 Gprof2dot 方法,但这仅显示isinstance()
正在被isinstance
和调用图调用在isinstance
停在那里。
有什么想法吗?
答案 0 :(得分:1)
我已经做了一些挖掘工作,并将至少部分地尝试回答我的问题(希望其他人能够看到并贡献出更多关于如何使之变得容易的想法)。
这就是我配置函数的方式
pr = cProfile.Profile() # create a cProfiler object
pr.enable() # turn profiling on
pr.runcall( myfunc, arg1, arg2, ... ) # profile my function
pr.disable() # turn profiling off
然后,这是找到呼叫者的关键:
import pstats
p = pstats.Stats(pr) # create pstats obj based on profiler above.
p.print_callers('isinstance') # find all the callers of isinstance.
print_callers
函数可打印出isinstance
的130个呼叫者,以及每个呼叫者呼叫isinstance
的次数。需要消化很多东西,但是出于分析的目的,将注意力集中在调用最多的几个上并找到他们的调用者是有意义的。这是列表的一部分(print_callers或多或少地以随机顺序显示,但是我已经根据调用次数对它们进行了排序)...
Function {built-in method builtins.isinstance} was called by...
ncalls tottime cumtime
2808 0.002 0.002 /anaconda3/lib/python3.7/site-packages/pandas/core/indexes/datetimes.py:974(get_loc)
2158 0.006 0.018 /anaconda3/lib/python3.7/site-packages/pandas/core/dtypes/base.py:75(is_dtype)
2030 0.001 0.001 /anaconda3/lib/python3.7/site-packages/pandas/core/dtypes/common.py:1845(_is_dtype_type)
1930 0.001 0.001 /anaconda3/lib/python3.7/site-packages/pandas/core/dtypes/common.py:1981(pandas_dtype)
1440 0.001 0.001 /anaconda3/lib/python3.7/site-packages/pandas/core/dtypes/dtypes.py:68(find)
1058 0.001 0.001 /anaconda3/lib/python3.7/site-packages/pandas/core/indexes/datetimes.py:924(get_value)
841 0.000 0.000 /anaconda3/lib/python3.7/site-packages/pandas/core/dtypes/common.py:1809(_get_dtype)
726 0.000 0.000 /anaconda3/lib/python3.7/site-packages/pandas/core/dtypes/common.py:1702(is_extension_arr
...
6 0.000 0.000 /anaconda3/lib/python3.7/site-packages/pandas/core/indexing.py:153(_get_setitem_indexer)
5 0.000 0.000 /anaconda3/lib/python3.7/site-packages/pandas/core/ops.py:1660(wrapper)
5 0.000 0.000 /anaconda3/lib/python3.7/site-packages/pandas/core/ops.py:1447(_align_method_SERIES)
5 0.000 0.000 /anaconda3/lib/python3.7/site-packages/pandas/core/computation/expressions.py:163(_has_bool_dtype)
4 0.000 0.000 /anaconda3/lib/python3.7/site-packages/pandas/core/internals/blocks.py:3100(_extend_blocks)
4 0.000 0.000 /anaconda3/lib/python3.7/site-packages/pandas/core/indexing.py:2501(check_setitem_lengths)
3 0.000 0.000 /anaconda3/lib/python3.7/site-packages/pandas/core/indexes/base.py:566(_shallow_copy)
3 0.000 0.000 /anaconda3/lib/python3.7/site-packages/pandas/core/dtypes/common.py:702(is_datetimelike)
3 0.000 0.000 /anaconda3/lib/python3.7/posixpath.py:41(_get_sep)
2 0.000 0.000 /anaconda3/lib/python3.7/distutils/version.py:331(_cmp)
在这一点上,我想我可以单调乏味地浏览最大的调用者(找到最大的调用者,依此类推)或编写脚本来做到这一点。将继续进行挖掘,并在以后发布其他进度。