IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Python代码优化工具——line_profile -> 正文阅读

[Python知识库]Python代码优化工具——line_profile

一、工具介绍

line_profiler是Python的一个第三方库,其功能时基于函数的逐行代码分析工具。通过该库,可以对目标函数(允许分析多个函数)进行时间消耗分析,便于代码调优。

二、安装

使用命令pip install line_profiler进行安装。

三、分析结果注解

先放上这个工具的分析结果,各位朋友可以看一下是否满足自己的要求,再决定是否安装以及使用。
分析结果
部分参数注解:

  • Timer unit:分析表中,Time和Per Hit的数值单位,时间单位固定为秒(s),默认数值单位是1e-6,合在一起便是1e-6s,即微秒。实际某一行的运行时间是Time * Timer unit的值,觉得不好理解的话,下方介绍kernprof命令时有一个示例供各位同学理解,这里只是简单提一下。
  • Total time:当前函数的时间消耗,单位是秒。
  • File:当前函数所在文件名。
  • Function:当前函数的函数名以及在文件中的位置。
  • Line #:代码所在行号。
  • Hits:在执行过程中,该行代码执行次数,即命中数。
  • Time:在执行过程中,该行代码执行的总时间,默认单位是微秒。
  • Per Hit:在执行过程中,平均每次执行该行代码所耗时间,默认单位是微秒。
  • % Time:执行该行代码所耗总时间占执行当前函数所耗总时间的百分比。
  • Line Contents:该行代码的内容。

分析结果保存位置
待代码执行完毕后,会在当前目录(注意,不是代码所在目录,而是执行命令的当前目录) 下生成一个后缀为.lprof的同名文件,该文件内存放的就是分析结果。

四、使用

line_profiler工具有三种使用姿势,各有利弊

1、使用kernprof命令进行分析

(1)使用姿势

在想要分析的函数前加上装饰器@profile,然后在终端数据使用命令kernprof进行分析。
github 网址
该命令的具体参数如下:

usage: kernprof [-h] [-V] [-l] [-b] [-o OUTFILE] [-s SETUP] [-v] [-u UNIT]
                [-z]
                script ...

Run and profile a python script.

positional arguments:
  script                The python script file to run
  args                  Optional script arguments

optional arguments:
  -h, --help            show this help message and exit
  -V, --version         show program's version number and exit
  -l, --line-by-line    Use the line-by-line profiler instead of cProfile.
                        Implies --builtin.
  -b, --builtin         Put 'profile' in the builtins. Use
                        'profile.enable()'/'.disable()', '@profile' to
                        decorate functions, or 'with profile:' to profile a
                        section of code.
  -o OUTFILE, --outfile OUTFILE
                        Save stats to <outfile> (default: 'scriptname.lprof'
                        with --line-by-line, 'scriptname.prof' without)
  -s SETUP, --setup SETUP
                        Code to execute before the code to profile
  -v, --view            View the results of the profile in addition to saving
                        it
  -u UNIT, --unit UNIT  Output unit (in seconds) in which the timing info is
                        displayed (default: 1e-6)
  -z, --skip-zero       Hide functions which have not been called
  • 简单来说,如果想用@profile装饰器的方式分析代码,就需要使用-l参数。
  • 默认分析结果会保存在.prof文件里,如果加了-l参数,则会将分析结果保存在.lprof文件里。
  • 可以使用python -m line_profiler <.lprof文件名>查看分析结果,此时不会再次执行代码,只是查询分析结果。
  • 如果需要在分析代码的同时打印分析结果,可以使用-v参数。
  • 默认情况下,@profile装饰了几个函数,就会出现几张分析表,如果某个函数没有被执行,则其Hit、Time等值显示为空。可以使用-z参数隐去未执行函数的分析结果。需要注意的是,-z参数只是在显示时隐藏了未执行函数的分析表,但不是不分析该函数,当使用python -m line_profiler <分析结果文件名>时,还是可以看到未执行函数的分析表的。
  • 想在分析代码之前,执行一些不加入分析的前置操作(比如配置环境变量等),可以使用-s <前置操作的.py文件名>,这样就会在执行分析代码所在的文件之前,先执行一遍前置操作文件。
  • 想将分析结果保存到指定的文件,而不是默认的文件里,可以使用-o [<文件路径>/]<文件名>来指定。文件后缀不一定非要.prof或者.lprof,经测试结果保存到.txt文件也是可以的,使用python -m line_profile <文件名.txt>同样可以显示结果。
  • 默认的时间数值单位,是1e-6,即微秒,我们可以通过-u <数值>来修改。以下是示例:函数功能是睡眠2秒,但因为Timer unit的数值单位不一样,其显示的数值也不一样,但代表的含是一样的。
    请添加图片描述

(2)示例:

代码如下,该示例共有三个函数,每个函数的功能都是睡眠一段时间后,构造10个随机数。

import random
import time

@profile
def function1():
    time.sleep(2)
    for _ in range(100):
        y = random.randint(1,100)


def function2():
    time.sleep(5)
    for _ in range(100):
        y = random.randint(1,100)


def function3():
    time.sleep(7)
    for _ in range(100):
        y = random.randint(1,100)

@profile
def main():
    function1()
    function2()
    function3()


if __name__ == "__main__":       
    main()

执行结果如下:
请添加图片描述
因为我只在mainfunction1函数加了装饰器,所以分析结果只有mainfunction1,实际使用时可以自行增加或减少函数。

(3)该姿势的利弊

优点

  • 不用在代码里导入第三方包,也不用修改代码的实际逻辑,有利于维持原代码的整体性。
  • 使用方便,只需在待分析的函数前加装饰器@profile即可。
  • 用于分析的函数可以不在同一个文件内,方便分析较为复杂、调用方法较多的程序。

缺点

  • 因为需要在所有待分析的函数前都需要加装饰器,所以添加和删除的麻烦度与待分析的函数的数量成正比。
  • 因为@profile并不是第三方导入的,所以正常运行代码时会报错。
  • 同样是因为@profile不是第三方导入的,在IDEA中该段代码会有代码错误的红色波浪线提示,强迫症震怒。

2、使用python命令进行分析

(1)使用姿势

需要在代码里引入第三方包LineProfiler,并在原代码里添加一些代码才可以实现,进行分析时就像平时执行代码一样python <文件名>即可。

(2)示例:

代码如下,该示例共有三个函数,每个函数的功能都是睡眠一段时间后,构造10个随机数。

import random
import time
from line_profiler import LineProfiler


def function1():
    time.sleep(2)
    for _ in range(100):
        y = random.randint(1,100)


def function2():
    time.sleep(5)
    for _ in range(100):
        y = random.randint(1,100)


def function3():
    time.sleep(7)
    for _ in range(100):
        y = random.randint(1,100)


def main():
    function1()
    function2()
    function3()


if __name__ == "__main__":
    lp = LineProfiler()  # 构造分析对象
    """如果想分析多个函数,可以使用add_function进行添加"""
    lp.add_function(function1)  # 添加第二个待分析函数
    lp.add_function(function2)  # 添加第三个待分析函数
    test_func = lp(main)  # 添加分析主函数,注意这里并不是执行函数,所以传递的是是函数名,没有括号。
    test_func()  # 执行主函数,如果主函数需要参数,则参数在这一步传递,例如test_func(参数1, 参数2...)
    lp.print_stats()  # 打印分析结果
    """
    坑点:
        1:test_func = lp(main)这一步,是实际分析的入口函数(即第一个被调用的函数,但不一定是main函数),所以这里封装的函数必须是测试脚本要执行的第一个函数。
        2:test_func()这一步才是真正执行,如果缺少这一步,代码将不会被执行
        3:lp.print_stats()这一步是打印分析结果,如果缺少这一步,将不会在终端看到分析结果。
        4:分析结果只与是否加入分析队列有关,而不管该函数是否被实际执行,如果该函数加入分析但没有被执行,则Hits、Time等值为空。
    """

执行结果如下:
请添加图片描述

(3)该姿势的利弊

优点

  • 添加/删除待分析函数方便,不用修改原代码,只需要在测试代码入口使用LineProfiler对象增加/删除待分析函数名即可。
  • 测试命令与平时运行代码的相同,不用增加学习负担。

缺点

  • 因为要导入第三方包以及创建LineProfiler对象,需要写一份专用于分析的测试脚本。
  • 分析多个函数时,是使用add_function+函数名来实现的,所以需要显示地导入待分析函数,或者将待分析函数拷贝到当前分析脚本,对较为复杂的逻辑很不友好。
  • 该姿势存在一些坑点,已在示例代码的备注中说明。
  • 不会将分析结果保存到.lprof文件中。

3、在Jupyter Notebook内使用line_profile

这一种姿势在实际工作中不常用,感兴趣的可以移步这位大佬的文章:line_profiler: Line by Line Profiling of Python Code

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-06-26 16:52:04  更:2022-06-26 16:52:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 3:48:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计