如何使用Python标准库进行性能测试

作者:烟火君 时间:2023-04-27 07:48:52 

Profile 和 cProfile

在 Python 标准库里面有两个模块可以用来做性能测试。

1. 一个是 Profile,它是一个纯 Python 的实现,所以会慢一些,如果你需要对模块进行拓展,那么这个模块比较合适。

2. 第二个是 cProfile,从名字就可以看出这是一个 C 语言的实现版,官方推荐在大多数情况下使用。
这两者的接口和数据的输出格式是完全一样的,你可以在这两者之间自由的切换,所以下面我们仅以 cProfile 为例进行介绍。

使用 cProfile 进行性能测试

在 cProfile 中,进行性能测试十分简单,只需调用 run 方法,并将需要测试的函数及参数传递给它即可,下面我们对fib(n) 进行性能测试。


import cProfile

def fib(n):
if n == 0:
return 0
if n == 1:
return 1
return fib(n-1) + fib(n-2)

if __name__ == '__main__':
cProfile.run('fib(30)')

性能测试的结果如下图

如何使用Python标准库进行性能测试

可以看到一共进行了 2692539 次函数调用,共耗时 0.815 秒。下面每一行对应于一个函数的调用情况,其中:

1. ncalls, 函数总共调用次数;
2. tottime, 这个函数调用总共花费时间;
3. percall, 每个调用的平均花费时间;
4. cumtime, 总共累计花费时间;
5. percall, 每个调用的平均累计时间;
6. filename:lineno(function), 对应函数信息。

所以从图中可以明显看到几乎的耗时都在fib上,而且函数调用数过多,这主要是因为函数是递归调用的,并且会产生很多冗余分支,所以程序需要进行优化。有两种方法进行改进,一是缓存fib(n)的信息,不需要每次都进行计算;二是将程序改为迭代式。

而对函数值进行缓存在 Python 3 里有一个简单的装饰器叫做lru_cache,可以自动的帮你缓存函数的值,而不需要自己手动存储。


import functools

@functools.lru_cache(maxsize=None)
def fib(n):
if n == 0:
return 0
if n == 1:
return 1
return fib(n-1) + fib(n-2)

运行结果如下:

如何使用Python标准库进行性能测试

可以看到,fib 函数只调用了 31 次,几乎所有额外的调用都命中了缓存,远远小于前面的调用次数,运行时间也得到了相当明显的提升。同时使用下面的迭代版程序也运行得非常快,这里就不再展开。


def fib(n):
prev, cur = 0, 1
if n == 0:
return prev
if n == 1:
return cur
count = 1
while count < n:
count += 1
prev, cur = cur, prev + cur
return cur

除了前面提到的 run 方法外,还有一个叫做 runctx 的方法,允许提供一些上下文参数。例如前面的 cProfile.run('fib(30)') 可以改为cProfile.runctx('fib', globals(), {'n':30})最后的运行结果是相同的。

最后,除了直接打印到命令行的方式,run 和 runctx 可以通过第二个参数传递文件名的方式将输出结果写入文件。

使用 pstats 对显示进行控制

cProfile 虽然可以对程序进行简单的性能测试,但是当程序过大,调用函数很多的时候,就需要一些对测试结果进行过滤和排序的工具了,而 pstats 就是这样的一个工具。


# fib_profile.py
import cProfile
import pstats

for i in range(5):
cProfile.run('fib(1000)', 'fib_profile_{}'.format(i))

stats = pstats.Stats('fib_profile_0')
for i in range(1, 5):
stats.add('fib_profile_{}'.format(i))
stats.strip_dirs()
stats.sort_stats('cumulative')
stats.print_stats('fib')

上面的程序首先写入了多个测试结果,然后初始化了 stats,可以通过 stats 的 add 方法添加新的文件,pstats 会自动的将结果聚合起来;然后 strip_dirs 将会移除文件名前面的路径,只保留文件名;sort_stats 是对输出结果进行排序,也就是在前面所说的那几行里进行选择(具体的可参阅官方文档);最后的 print_stats 对结果进行输出,在这面可以对行进行过滤,比如上面的程序就只输出了包含 fib 的行;实际输出结果如下。

如何使用Python标准库进行性能测试

来源:https://blog.csdn.net/preyta/article/details/66474263

标签:python,标准库,性能测试
0
投稿

猜你喜欢

  • Keras 在fit_generator训练方式中加入图像random_crop操作

    2023-10-31 23:05:51
  • 对Python _取log的几种方式小结

    2021-12-19 02:18:48
  • JavaScript实现点击改变图片形状(transform应用)

    2024-05-13 09:18:32
  • 学习ASP.NET八天入门:第一天

    2007-08-07 13:08:00
  • 在Python的Django框架中为代码添加注释的方法

    2023-09-25 07:24:21
  • js检测浏览器语种,适合于多语言版本的站点

    2007-09-12 19:16:00
  • python验证身份证信息实例代码

    2022-11-19 13:36:24
  • python 三种方法提取pdf中的图片

    2023-09-18 08:25:58
  • Python中内置数据类型list,tuple,dict,set的区别和用法

    2022-09-10 05:59:46
  • Python实现复制图片到指定文件夹并按顺序重新命名

    2022-04-25 18:53:06
  • js原生map实现的方法总结

    2024-04-10 10:47:34
  • python TK库简单应用(实时显示子进程输出)

    2023-10-08 23:08:19
  • 怎么检测到点击图片的左右位置 像QQ空间那样

    2008-10-04 10:45:00
  • Python容器类型转换的3种方法实例

    2022-06-03 13:32:32
  • request基本使用及各种请求方式参数的示例

    2021-03-31 02:32:52
  • Git操作规范之tag的使用技巧详解

    2022-07-30 05:10:54
  • 详解基于python-django框架的支付宝支付案例

    2023-01-07 12:30:22
  • 对Django中static(静态)文件详解以及{% static %}标签的使用方法

    2021-03-27 20:28:21
  • python3 pillow生成简单验证码图片的示例

    2022-08-16 23:17:05
  • 微信小程序实现搜索功能

    2024-05-02 16:17:16
  • asp之家 网络编程 m.aspxhome.com