在编译的Cython代码上使用line-profiler(在ipython中)

时间:2017-01-29 21:13:34

标签: python cython line-profiler

我已阅读此问题How to profile cython functions line-by-line的答案,但我似乎无法使用我的设置。

我有cumsum.pyx个文件:

# cython: profile=True
# cython: linetrace=True
# cython: binding=True
DEF CYTHON_TRACE = 1

def cumulative_sum(int n):
    cdef int s=0, i
    for i in range(n):
        s += i

    return s

我编译它:

cython cumsum.pyx
gcc cumsum.c $(pkg-config --cflags --libs python3) -o cumsum.so -shared -fPIC

然后我尝试在ipython中对其进行分析:

%load_ext line_profiler
from cumsum import cumulative_sum
%lprun -f cumulative_sum cumulative_sum(100)

我没有收到错误消息,只有空配置文件:

Timer unit: 1e-06 s

Total time: 0 s
File: cumsum.pyx
Function: cumulative_sum at line 6

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     6                                           def cumulative_sum(int n):
     7                                               cdef int s=0, i
     8                                               for i in range(n):
     9                                                   s += i
    10                                           
    11                                               return s

我怎样才能让它发挥作用?

PS:我使用的是CMake,而不是setup.py,所以我很感激构建系统无关的解决方案

2 个答案:

答案 0 :(得分:1)

documentation on Cythons "Profiling"已经包含了如何设置CYTHON_TRACE宏的示例:

# distutils: define_macros=CYTHON_TRACE_NOGIL=1

而不是DEF CYTHON_TRACE = 1

当我使用%%cython编译它时,它有效:

%load_ext cython
%%cython

# cython: profile=True
# cython: linetrace=True
# cython: binding=True
# distutils: define_macros=CYTHON_TRACE_NOGIL=1

def cumulative_sum(int n):
    cdef int s=0, i
    for i in range(n):
        s += i
    return s

并展示了分析:

%load_ext line_profiler
%lprun -f cumulative_sum cumulative_sum(100)
[...]
Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     7                                           def cumulative_sum(int n):
     8         1            8      8.0      3.5      cdef int s=0, i
     9         1            3      3.0      1.3      for i in range(n):
    10       100          218      2.2     94.4          s += i
    11         1            2      2.0      0.9      return s

答案 1 :(得分:0)

原来问题是DEF CYTHON_TRACE = 1实际上没有设置正确的常量。

解决方法包括:

1。 MSeifert's answer,使用distutils

2。 将gcc行更改为

gcc cumsum.c $(pkg-config --cflags --libs python3) -o cumsum.so -shared -fPIC -DCYTHON_TRACE=1

3。 制作额外的标题trace.h并在那里设置常量

 #define CYTHON_TRACE 1

并将以下内容添加到cumsum.pyx

cdef extern from "trace.h":
    pass

4。 使用CMake,添加

add_definitions(-DCYTHON_TRACE)