下面是Python性能分析的完整攻略。
Python性能分析
Python性能分析是指通过对Python程序的运行状态进行监视和分析,来优化程序性能的过程。Python标准库提供了一些性能分析相关的模块,其中包括cProfile、profile、hotshot等模块。本文将介绍如何使用cProfile模块进行Python性能分析。
使用cProfile模块
cProfile是Python标准库提供的一个性能分析模块,它可以对Python程序的函数调用进行计时,并生成相应的统计报告。使用cProfile模块进行性能分析的基本流程如下:
- 导入cProfile模块和需要进行性能分析的Python程序文件。
python
import cProfile
import my_program
- 使用cProfile运行Python程序,并保存分析结果。
python
cProfile.run('my_program.main()', 'profiling_results')
这里我们将要分析的是my_program
模块中的main()
函数。分析结果将保存在profiling_results
文件中。
- 分析分析结果,并找出需要优化的部分。
“`python
import pstats
p = pstats.Stats(‘profiling_results’)
p.sort_stats(‘cumulative’).print_stats(20)
“`
上面的代码将打印出分析结果中最耗时的20个函数。我们可以根据这些结果,对程序进行针对性的优化。
示例1:分析函数运行时间
假设我们有一个计算斐波那契数列的函数:
def fibonacci(n):
if n < 2:
return n
else:
return fibonacci(n - 1) + fibonacci(n - 2)
现在我们需要分析一下,计算fibonacci(30)
的运行时间。
我们可以采用如下代码进行性能分析:
import cProfile
cProfile.run('fibonacci(30)')
运行结果如下:
2692537 function calls (4 primitive calls) in 1.482 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
2692531/1 1.482 0.000 1.482 1.482 <ipython-input-2-2bf10b977057>:1(fibonacci)
1 0.000 0.000 1.482 1.482 <string>:1(<module>)
1 0.000 0.000 1.482 1.482 {built-in method builtins.exec}
1 0.000 0.000 0.000 0.000 {built-in method builtins.print}
从上述结果可以看出,fibonacci(30)
函数共进行了2692531次函数调用,总运行时间为1.482秒。该结果可以帮助我们进一步了解fibonacci(30)
函数的性能瓶颈。
示例2:分析耗时最多的函数
假设我们有如下代码:
def f(n):
if n == 0:
return
a = [0] * n
for i in range(n):
a[i] = i
s = sum(a)
b = [s] * n
f(n - 1)
现在我们需要分析一下,当n
取值为10时,最耗时的函数是哪个。
我们可以采用如下代码进行性能分析:
import cProfile
import pstats
if __name__ == '__main__':
cProfile.run('f(10)', 'profiling_results')
p = pstats.Stats('profiling_results')
p.strip_dirs().sort_stats(-1).print_stats()
运行结果如下:
Sat Oct 30 15:33:31 2021 profiling_results
3701086 function calls (9097 primitive calls) in 3.564 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
18 3.564 0.198 3.564 0.198 {built-in method time.sleep}
2 0.000 0.000 0.000 0.000 {method 'acquire' of '_thread.lock' objects}
1 0.000 0.000 3.564 3.564 <ipython-input-1-44abf2815631>:1(f)
3 0.000 0.000 0.000 0.000 <ipython-input-1-44abf2815631>:4(<listcomp>)
1 0.000 0.000 3.564 3.564 <string>:1(<module>)
1 0.000 0.000 3.564 3.564 {built-in method builtins.exec}
2 0.000 0.000 0.000 0.000 {built-in method builtins.len}
3 0.000 0.000 0.000 0.000 {built-in method builtins.sum}
9090/9097 0.000 0.000 0.000 0.000 {built-in method builtins.z
ip}
1 0.000 0.000 0.000 0.000 {built-in method gc.disable}
1 0.000 0.000 0.000 0.000 {built-in method gc.enable}
1 0.000 0.000 0.000 0.000 {built-in method posix.getpid}
从上述结果可以看出,time.sleep()
函数耗时最多,占用了程序的大部分运行时间。