I have developed a python C-extension that receives data from python and compute some cpu intensive calculations. It's possible to profile the C-extension?
The problem here is that writing a sample test in C to be profiled would be challenging because the code rely on particular inputs and data structures (generated by python control code).
Do you have any suggestions?
After the comment by pygabriel I decided to upload a package to pypi that implements a profiler for python extensions using the cpu-profiler from google-perftools: http://pypi.python.org/pypi/yep
With gprof, you can profile any program that was properly compiled and linked (
gcc -pg
etc, ingprof
's case). If you're using a Python version not built withgcc
(e.g., the Windows precompiled version the PSF distributes), you'll need to research what equivalent tools exist for that platform and toolchain (in the Windows PSF case, maybemingw
can help). There may be "irrelevant" data there (internal C functions in the Python runtime), and, if so, the percentages shown bygprof
may not be applicable -- but the absolute numbers (of calls, and durations thereof) are still valid, and you can post-processgprof
's output (e.g., with a little Python script;-) to exclude the irrelevant data and compute the percentages you want.I've found my way using google-perftools. The trick was to wrap the functions StartProfiler and StopProfiler in python (throught cython in my case).
To profile the C extension is sufficient to wrap the python code inside the StartProfiler and StopProfiler calls.
Then to analyze for example you can export in callgrind format and see the result in kcachegrind:
One of my colleague told me
ltrace(1)
. It helped me on the same situation quite a lot.Assume the shared object name of your C extention is
myext.so
and you want to executebenchmark.py
, thenIts output is like
Special care is needed if your shared object has
-
or+
in its file name. These characters aren't treated as is (seeman 1 ltrace
for details).The wildcard
*
can be a workaround such as-x @myext*
in place of-x @myext-2.so
.