在Jupyter Notebook中使用cython进行行轮廓分析 [英] Line profiling with cython in jupyter notebook
问题描述
我正在尝试在具有cython功能的jupyter笔记本中使用Liner_profiler库.它只在中途工作.我得到的结果仅包含该函数的第一行,而没有分析结果.
I'm trying to use liner_profiler library in jupyter notebook with cython function. It is working only halfway. The result I get only consist of first row of the function and no profiling results.
%%cython -a
# cython: linetrace=True
# cython: binding=True
# distutils: define_macros=CYTHON_TRACE_NOGIL=1
import numpy as np
cimport numpy as np
from datetime import datetime
import math
cpdef np.int64_t get_days(np.int64_t year, np.int64_t month):
cdef np.ndarray months=np.array([31,28,31,30,31,30,31,31,30,31,30,31])
if month==2:
if (year%4==0 and year%100!=0) or (year%400==0):
return 29
return months[month-1]
对于分析结果,int只能显示一行代码
For the profiling result int onlt shows one line of code
Timer unit: 1e-07 s
Total time: 0.0015096 s
File: .ipython\cython\_cython_magic_0154a9feed9bbd6e4f23e57d73acf50f.pyx
Function: get_days at line 15
Line # Hits Time Per Hit % Time Line Contents
==============================================================
15 cpdef np.int64_t get_days(np.int64_t year, np.int64_t month):
推荐答案
这可以看作是line_profiler
中的错误(如果应该支持Cython).要获取配置文件功能的代码,line_profiler
读取pyx
-文件,并尝试在inspect.getblock
的帮助下提取代码:
This can be seen as a bug in the line_profiler
(if it is supposed to support Cython). To get the code of the profiled function, line_profiler
reads the pyx
-file and tries to extract the code with help of inspect.getblock
:
...
# read pyx-file
all_lines = linecache.getlines(filename)
# try to extract body of the function strarting at start_lineno:
sublines = inspect.getblock(all_lines[start_lineno-1:])
...
但是,getblock
对cpdef
函数一无所知,因为python仅具有def
函数,因此产生错误的函数体(即仅签名).
However, getblock
knows nothing about cpdef
-function, as python has only def
-functions and thus yields wrong function-body (i.e. only the signature).
解决方法:
一个简单的解决方法是引入一个虚拟def
函数,该函数将成为cpdef
函数的哨兵,从而使inspect.getblock
产生cpdef函数的整个主体+前哨功能的主体,即:
A simple work around would be to introduce a dummy def
-function, which would be a sentinel for the cpdef
-function in such a way, that inspect.getblock
would yield the whole body of the cpdef-function + body of the the sentinel function, i.e.:
%%cython
...
cpdef np.int64_t get_days(np.int64_t year, np.int64_t month):
...
def get_days_sentinel():
pass
,现在报告%lprun -f get_days get_days(2019,3)
如下所示:
Timer unit: 1e-06 s
Total time: 1.7e-05 s
File: XXXX.pyx
Function: get_days at line 10
Line # Hits Time Per Hit % Time Line Contents
==============================================================
10 cpdef np.int64_t get_days(np.int64_t year, np.int64_t month):
11 1 14.0 14.0 82.4 cdef np.ndarray months=np.array([31,28,31,30,31,30,31,31,30,31,30,31])
12 1 1.0 1.0 5.9 if month==2:
13 if (year%4==0 and year%100!=0) or (year%400==0):
14 return 29
15 1 2.0 2.0 11.8 return months[month-1]
16
17 def get_days_sentinel():
18 pass
前哨上还有一些难看的尾随线,但最好是根本不看任何东西.
There are still somewhat ugly trailing lines from the sentinel, but it is probably better as not seeing anything at all.
这篇关于在Jupyter Notebook中使用cython进行行轮廓分析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!