
line_profiler是Python的一个第三方库,其功能时基于函数的逐行代码分析工具。通过该库,可以对目标函数(允许分析多个函数)进行时间消耗分析,便于代码调优。
二、安装使用命令pip install line_profiler进行安装。
三、分析结果注解先放上这个工具的分析结果,各位朋友可以看一下是否满足自己的要求,再决定是否安装以及使用。
部分参数注解:
分析结果保存位置
待代码执行完毕后,会在当前目录(注意,不是代码所在目录,而是执行命令的当前目录) 下生成一个后缀为.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 (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
代码如下,该示例共有三个函数,每个函数的功能都是睡眠一段时间后,构造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()
执行结果如下:
因为我只在main和function1函数加了装饰器,所以分析结果只有main和function1,实际使用时可以自行增加或减少函数。
优点
缺点
需要在代码里引入第三方包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等值为空。
"""
执行结果如下:
优点
缺点
这一种姿势在实际工作中不常用,感兴趣的可以移步这位大佬的文章:line_profiler: Line by Line Profiling of Python Code