如何逐行分析Cython函数性能,同时获取Python与C++函数运行耗时
解决方案
1. 修正Cython编译配置
你当前已经开启了基础的性能分析配置,但要支持逐行分析和底层C++耗时统计,需要补充调试和栈帧保留编译参数,修正后的代码如下:
from Cython.Compiler.Options import get_directive_defaults directive_defaults = get_directive_defaults() directive_defaults['linetrace'] = True directive_defaults['binding'] = True directive_defaults['profile'] = True %load_ext cython
%%cython --compile-args=-g --compile-args=-fno-omit-frame-pointer --link-args=-g from pygpb import libgpb import numpy as np from skimage import io, color import matplotlib.pyplot as plt from skimage import io import os import sys from timeit import default_timer as timer @profile # 标记需要逐行分析的函数 def main(path): n_ori, Kmean_num, sigma_sm, sigma_lg = 8, 64, 2.0, np.sqrt(2)*2.0 # run it gpb = libgpb.Gpb() img = io.imread(path) if(img.strides[1] > 3): img = (255 * color.rgba2rgb(img)).astype(np.uint8) gpb.test_np_mat(img, img) # get texton texton = gpb.texton(img, n_ori, Kmean_num, sigma_sm, sigma_lg) start = timer(); gpb_res, ucm_res = gpb.run(img) end = timer(); print("Time taken by demo is : " ,end-start, "seconds")

2. 逐行分析Cython函数耗时
%prun是Python层面的cProfile封装,仅能统计Python可识别的函数调用耗时,无法深入Cython行和C++层,逐行分析Cython需要使用line_profiler工具:
- 安装依赖:
pip install line_profiler - 在Jupyter中加载扩展:
%load_ext line_profiler - 运行逐行分析命令:
%lprun -f main main("你的测试图片路径") - 输出结果会展示
main函数每一行的执行次数、耗时、占比,包括调用C++接口的行总耗时。
3. 统计底层C++函数内部耗时
如果需要进一步查看libgpb库中C++函数的内部耗时分布,需要使用系统级性能剖析工具:
- Linux环境:使用perf工具
- 确保编译
libgpb库时也添加了-g -fno-omit-frame-pointer参数,保留调试信息和栈帧 - 执行剖析命令:
!perf record -g python -c "from your_script import main; main('测试图片路径')" - 查看分析结果:
!perf report,可以看到从Python到Cython再到C++的全栈耗时分布。
- 确保编译
- Windows环境:使用Intel VTune进行全栈性能分析
- macOS环境:使用系统自带的Instruments工具的Time Profiler模板
注意事项
- 调试和性能分析参数会降低代码运行速度,仅在性能调优阶段使用,正式发布时需要移除
- 如果C库没有开启调试信息,性能剖析工具只能显示函数地址,无法显示函数名和行号,需要重新编译C依赖库时添加对应编译参数
内容的提问来源于stack exchange,提问作者Aditya Sriram
相关产品推荐
相关产品推荐

