0
点赞
收藏
分享

微信扫一扫

Cython—性能分析


文章目录


在cython加速中,通过profile性能分析工具分析不同含函数的运行耗时。


以下代码运行在jupyter notebook上

这里以以下公式作为一个小例子,我们将会估计到一个特定整数值n的倒数平方和来估计圆周率。我们想用的这个关系由欧拉在1735年证明,在巴塞尔问题中很著名。

一个python代码

import pstats,cProfile


def recip_square(i):
return 1.0/(i**2)

def approx_pi(n=10000000):
val = 0.0
for k in range(1,n+1):
val +=recip_square(k)
return (6*val)**0.5


cProfile.runctx("approx_pi()",globals(),locals(),"Profile.prof")
s = pstats.Stats("Profile.prof")
s.strip_dirs().sort_stats("time").print_stats()

=======================运行输出=======================
Thu Mar 12 15:33:12 2020 Profile.prof

10000004 function calls in 5.402 seconds

Ordered by: internal time

ncalls tottime percall cumtime percall filename:lineno(function)
10000000 3.767 0.000 3.767 0.000 <ipython-input-4-d6372d80493e>:1(recip_square)
1 1.636 1.636 5.402 5.402 <ipython-input-4-d6372d80493e>:5(approx_pi)
1 0.000 0.000 5.402 5.402 {built-in method builtins.exec}
1 0.000 0.000 5.402 5.402 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}

Type

备注

ncalls

函数被调用的次数

tottime

函数内部消耗的总时间

percall

函数的平均调用时间,tottime/ncalls

cumtime

之前所有子函数消费时间的累计和

filename:lineno(function)

被分析函数所在文件名、行号、函数名。

写成cython
以下n,i使用 int 会数据长度溢出报错,改成 long long 。
recip_square()使用C++中的内联函数声明方式。同时:i**2改写成i*i,这个各位可以测试一下:

%load_ext Cython
%%cython --annotate

cdef inline double recip_square(long long i):
return 1.0/(i*i)


def C_approx_pi(long long n=10000000):
cdef double val = 0.0
cdef int k
for k in range(1,n+1):
val +=recip_square(k)
return (6*val)**0.5


cProfile.runctx("C_approx_pi()",globals(),locals(),"Profile.prof")
s = pstats.Stats("Profile.prof")
s.strip_dirs().sort_stats("time").print_stats()


=======================运行输出=======================
Thu Mar 12 16:05:02 2020 Profile.prof

4 function calls in 0.013 seconds

Ordered by: internal time

ncalls tottime percall cumtime percall filename:lineno(function)
1 0.012 0.012 0.012 0.012 {_cython_magic_376fc8b7c10a202ad2fdeb563e2323aa.C_approx_pi}
1 0.000 0.000 0.013 0.013 <string>:1(<module>)
1 0.000 0.000 0.013 0.013 {built-in method builtins.exec}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}

若是不需要监控的函数,可以注销该函数监测,比如:

%%cython --annotate
import cython


@cython.profile(False) # 添加此代码
cdef inline double recip_square(long long i):
return 1.0/(i*i)


def C_approx_pi(long long n=10000000):
cdef double val = 0.0
cdef int k
for k in range(1,n+1):
val +=recip_square(k)
return (6*val)**0.5

cProfile.runctx("C_approx_pi()",globals(),locals(),"Profile.prof")
s = pstats.Stats("Profile.prof")
s.strip_dirs().sort_stats("time").print_stats()

=======================运行输出=======================
Thu Mar 12 16:08:47 2020 Profile.prof

4 function calls in 0.010 seconds

Ordered by: internal time

ncalls tottime percall cumtime percall filename:lineno(function)
1 0.010 0.010 0.010 0.010 {_cython_magic_58c1ce2f1baf89864f3cbe41ed0c4287.C_approx_pi}
1 0.000 0.000 0.010 0.010 <string>:1(<module>)
1 0.000 0.000 0.010 0.010 {built-in method builtins.exec}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}

参考:http://docs.cython.org/en/latest/src/tutorial/profiling_tutorial.html


举报

相关推荐

0 条评论