爱上python系列------python性能(二):line

it2023-05-19  71

Python的性能分析分析十分重要,因为可以给我们优化性能提供可靠的数值参考

Python的性能分析有两个主流工具cProfileline_profiler,前者是python内置的工具,不过不是分析报告特别详细

下面试一下cProfile:

import profile class cached: def __init__(self, fn): self.fn = fn self.cache = {} def __call__(self, *args): try: return self.cache[args] except KeyError: self.cache[args] = self.fn(*args) return self.cache[args] @cached def fib(n): if n <= 1:return n else:return fib(n-1) + fib(n-2) def fib_seq(n): seq = [] if n > 0: seq.extend(fib_seq(n-1)) seq.append(fib(n)) return seq if __name__ == '__main__': #print(fib_seq(20)) profile.run('print(fib_seq(200)); print')

运行结果如下:

11521 function calls (8023 primitive calls) in 0.009 seconds Ordered by: cumulative time ncalls tottime percall cumtime percall filename:lineno(function) 2505/5 0.005 0.000 0.008 0.002 78797.py:19(fib_seq) 2500 0.001 0.000 0.001 0.000 {method 'extend' of 'list' objects} 3503/2505 0.001 0.000 0.001 0.000 78797.py:7(__call__) 5 0.001 0.000 0.001 0.000 {built-in method builtins.print} 501 0.000 0.000 0.001 0.000 78797.py:15(fib) 2505 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects} 1 0.000 0.000 0.000 0.000 cProfile.py:50(create_stats) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} Ordered by: cumulative time Function was called by... ncalls tottime cumtime 78797.py:19(fib_seq) <- 2500/5 0.005 0.008 78797.py:19(fib_seq) {method 'extend' of 'list' objects} <- 2500 0.001 0.001 78797.py:19(fib_seq) 78797.py:7(__call__) <- 998 0.000 0.000 78797.py:15(fib) 2505 0.001 0.001 78797.py:19(fib_seq) {built-in method builtins.print} <- 78797.py:15(fib) <- 501 0.000 0.001 78797.py:7(__call__) {method 'append' of 'list' objects} <- 2505 0.000 0.000 78797.py:19(fib_seq) cProfile.py:50(create_stats) <- {method 'disable' of '_lsprof.Profiler' objects} <- 1 0.000 0.000 cProfile.py:50(create_stats)

注:只写了报告内容,print的内容没有贴出来

我们可以从结果中看到函数调用的概要

不过没法像line_profiler可以按行给出分析报告

line_profiler的使用之前需要安装:

pip3 install line_profiler

安装成功就可以使用了,在使用之前值得一提的是,kernprof是line_profiler工具,在pip3 install line_profiler结束后已经安装好了,不信我们可以试一下:

root@root:/opt/pypy3.7-v7.3.2-linux64# kernprof Usage: kernprof [-s setupfile] [-o output_file_path] scriptfile [arg] ...

接下来使用kernprof进行分析,在这之前需要建立一个名为tt.py的python文件,内容如:

@profile def run(): a = [1]*100 b = [x**3 for x in a ] c = [x for x in b] d = c*2 run()

 接下来就是见证奇迹的时候了:

kernprof -l -v tt.py

结果:

Timer unit: 1e-06 s Total time: 4e-05 s File: tt.py Function: run at line 1 Line # Hits Time Per Hit % Time Line Contents ============================================================== 1 @profile 2 def run(): 3 1 3.0 3.0 7.5 a = [1]*100 4 1 28.0 28.0 70.0 b = [x**3 for x in a ] 5 1 8.0 8.0 20.0 c = [x for x in b] 6 1 1.0 1.0 2.5 d = c*2

同时会在当前路径下面 生成一个名为.lprof的文件

 这个文件可以理解成刚才运行的报告的持久化的文件,可以读出来的:

root@root:/opt/pypy3.7-v7.3.2-linux64# python3 -m line_profiler tt.py.lprof Timer unit: 1e-06 s Total time: 4e-05 s File: tt.py Function: run at line 1 Line # Hits Time Per Hit % Time Line Contents ============================================================== 1 @profile 2 def run(): 3 1 3.0 3.0 7.5 a = [1]*100 4 1 28.0 28.0 70.0 b = [x**3 for x in a ] 5 1 8.0 8.0 20.0 c = [x for x in b] 6 1 1.0 1.0 2.5 d = c*2

我们可以看到和运行的时候一样,我们发现装饰器@就能进行性能分析,是不是很方便呢

最新回复(0)