pyg*_*iel 36 c python profiling
我开发了一个python C扩展,它从python接收数据并计算一些cpu密集型计算.可以分析C扩展吗?
这里的问题是在C中编写样本测试以进行分析将是一项挑战,因为代码依赖于特定的输入和数据结构(由python控制代码生成).
你有什么建议吗?
pyg*_*iel 19
我找到了使用google-perftools的方法.诀窍是将函数StartProfiler和StopProfiler包装在python中(在我的情况下通过cython).
要分析C扩展名就足以将python代码包装在StartProfiler和StopProfiler调用中.
from google_perftools_wrapped import StartProfiler, StopProfiler
import c_extension # extension to profile c_extension.so
StartProfiler("output.prof")
... calling the interesting functions from the C extension module ...
StopProfiler()
Run Code Online (Sandbox Code Playgroud)
然后分析例如你可以用callgrind格式导出并在kcachegrind中看到结果:
pprof --callgrind c_extension.so output.prof > output.callgrind
kcachegrind output.callgrind
Run Code Online (Sandbox Code Playgroud)
我的一位同事告诉我 ltrace(1)。在同样的情况下,它对我帮助很大。
假设您的 C 扩展的共享对象名称是myext.so并且您想要执行benchmark.py,然后
ltrace -x @myext.so -c python benchmark.py
Run Code Online (Sandbox Code Playgroud)
它的输出就像
% time seconds usecs/call calls function
------ ----------- ----------- --------- --------------------
24.88 30.202126 7550531 4 ldap_result
12.46 15.117625 7558812 2 l_ldap_result4
12.41 15.059652 5019884 3 ldap_chase_v3referrals
12.41 15.057678 3764419 4 ldap_new_connection
12.40 15.050310 3762577 4 ldap_int_open_connection
12.39 15.042360 3008472 5 ldap_send_server_request
12.38 15.029055 3757263 4 ldap_connect_to_host
0.05 0.057890 28945 2 ldap_get_option
0.04 0.052182 26091 2 ldap_sasl_bind
0.03 0.030760 30760 1 l_ldap_get_option
0.03 0.030635 30635 1 LDAP_get_option
0.02 0.029960 14980 2 ldap_initialize
0.02 0.027988 27988 1 ldap_int_initialize
0.02 0.026722 26722 1 l_ldap_simple_bind
0.02 0.026386 13193 2 ldap_send_initial_request
0.02 0.025810 12905 2 ldap_int_select
....
Run Code Online (Sandbox Code Playgroud)
如果您的共享对象在其文件名中有-或+,则需要特别小心。这些字符不会按原样处理(请参阅man 1 ltrace有关详细信息,)。
通配符*可以是一种解决方法,例如-x @myext*代替-x @myext-2.so.