python性能分析之装饰器实现输出每一行代码执行时间

1,135 阅读2分钟

这是我参与2022首次更文挑战的第28天,活动详情查看2022首次更文挑战

作为一个程序员而言,学会性能分析是一件很重要的事,特别是对于python程序员而言,由于语言本身的缺点,本身的执行效率就很低。虽然并不是我们编写的每一个python程序都需要进行严格的性能分析,但是遇到特殊场景我们也需要学会如何检查,值得庆幸的是python有很多库和工具来使用。

下面我们就来介绍一下line_profiler

Robert Kern 有一个名为line_profiler的好项目,我经常使用它来查看每行代码在我的脚本中运行的速度和频率。

要使用它,您需要通过 pip 安装 python 包:

pip install wrapt

安装后,您将可以访问一个名为“line_profiler”的新模块以及一个可执行脚本。

要使用此工具,首先通过使用装饰器装饰要测量的函数来修改源代码@profile。别担心,你不必为了使用这个装饰器而导入任何东西。该test.py脚本会在执行期间自动将其注入脚本的运行时 @profile使用装饰器设置代码后,请使用它kernprof.py来运行脚本。

$ test.py -l -v fib.py

-l选项告诉 kernprof 将@profile装饰器注入到脚本的内置函数中,并-v告诉 kernprof 在脚本完成后显示时间信息。

下面是实操:

首先安装line_profiler和wrapt包 pip install line_profiler 在这里插入图片描述 pip install wrapt 在这里插入图片描述 装饰器:

import wrapt
from line_profiler import LineProfiler
lp = LineProfiler()
 
def lp_wrapper():
    @wrapt.decorator
    def wrapper(func, instance, args, kwargs):
        global lp
        lp_wrapper = lp(func)
        res = lp_wrapper(*args, **kwargs)
        lp.print_stats()
        return res
 
    return wrapper

放到需要查看的文件中即可,也可放到公共库里,这里就放到测试文件里:

import wrapt
from line_profiler import LineProfiler

lp = LineProfiler()


def lp_wrapper():
    """
    显示函数调用时间
    """

    @wrapt.decorator
    def wrapper(func, instance, args, kwargs):
        global lp
        lp_wrapper = lp(func)
        res = lp_wrapper(*args, **kwargs)
        lp.print_stats()
        return res

    return wrapper

@lp_wrapper()
def demo():
    # 执行的函数
    pass

demo()

**结果:**此结果非上述代码的输出 在这里插入图片描述 截图中最长的消耗了6.7秒 这种方法是目前我所能知道的最方便的查看方法,只需要安装包写个装饰器即可,当函数被调用时即可查看被装饰的函数的详情。