line_profiler增强,运行脚本无需删除@profile装饰器

来源:互联网 发布:漯河淘宝加盟被骗了 编辑:程序博客网 时间:2024/06/05 20:02

什么是line_profiler

用惯了MATLAB的人转移到Python上,优化程序的第一步应该就是找profile。Python的确内置profiler,有两种:profile和cProfile,一个是Python写的,另一个是用C写的扩展。自带的profiler输出结果较为完善,各个内建函数也都包含在内,但对于不那么熟悉Python内建函数的新手来讲,通过自带profiler去优化一段程序很难完成。

有一些现成的第三方包给内置profiler的输出文件做了扩展,可将其调用过程展示在GUI里,但无论如何还是没有每行代码单独统计时间来的方便。就算知道某个内建函数费时较多,但为了优化程序,还需找出调用此内建函数的语句,所以很有可能出现一个你的函数调用了一个内建函数,而它又调用了另一个内建函数,这就使得整个程序优化过程十分繁琐。

line_profiler很好的解决了这个问题,其输出结果就如同MATLAB中profile的输出结果,按照每行代码统计耗时以及调用次数。可从github上下载,其页面上有很详细的使用说明,这里就不介绍其使用方法。下载页面:

https://github.com/rkern/line_profiler

line_profiler增强

学会使用line_profiler后,发现其优化方式方便是方便,但对于函数很多的大段程序,或者对于包含很多方法的自建类的优化就没那么方便了。因为要使用line_profiler,需要再你想要time的函数前一行增加@profile装饰器,例如:

# 不使用line_profilerdef example1():    print('This is an example without profiling')# 使用line_profiler@profiledef example2():    print('This is an example with profiling')

但是在加上@profile装饰器后,程序无法直接运行,要想在类似spyder这种类MATLAB的IDE中边优化、边调试就很困难。优化之前要在函数前加上@profile,调试时又要将@profile删掉,整个过程很麻烦。无意间在书中看到既可以不删除@profile,又可以正常调试程序的方法。方法出自:

High Performance Python by Micha Gorelick and Ian Ozsvald

将以下代码加入脚本最前面,如果是类的话,加在类的定义之前。

if '__builtin__' not in dir() or not hasattr(__builtin__, 'profile'):    def profile(func):        def inner(*args, **kwargs):            return func(*args, **kwargs)        return inner

书中给的代码仅适用于python2,因为python2和python3对于__builtin__的定义有些变化。适用于python3的代码如下,放在脚本最前面即可使用。

if 'builtins' not in dir() or not hasattr(builtins, 'profile'):    import builtins    def profile(func):        def inner(*args, **kwargs):            return func(*args, **kwargs)        return inner    builtins.__dict__['profile'] = profile

该方法的原理是在不使用line_profiler时重新定义一个@profile装饰器,装饰器的作用是运行被装饰函数,除此之外没有其他作用,最后将其加入到环境变量的函数列表中即可。

0 0
原创粉丝点击