Python学习笔记25:进阶篇(十四)常见标准库使用之性能测试timeit模块学习使用

前言

本文是根据python官方教程中标准库模块的介绍,自己查询资料并整理,编写代码示例做出的学习笔记。

根据模块知识,一次讲解单个或者多个模块的内容。

教程链接:https://docs.python.org/zh-cn/3/tutorial/index.html

性能测量

Python中的性能测试主要关注于评估代码执行速度、资源消耗(如内存使用)及扩展性等方面。这有助于开发者识别并优化程序中的瓶颈,确保应用能够高效运行。

水平有限,讲一些关键概念和实践方法,简单写点代码运行一下。

  1. 基准测试 (Benchmarking)
    目的: 基准测试是评估代码片段或整个应用程序在特定条件下的执行性能,通常用来比较不同实现方式的效率。
    工具: 使用 timeit 模块进行简单的重复执行计时,或者 pytest-benchmark 这样的第三方库进行更复杂的测试场景。
    实践: 设定明确的测试环境(如数据集大小、硬件配置),确保测试结果可复现和比较。
  2. 性能剖析 (Profiling)
    目的: 细致地分析代码中各个部分的执行时间,找出耗时最长的部分(热点)。
    工具:
    cProfile:Python 标准库中的性能剖析器,提供函数级别的性能报告。
    line_profiler:第三方库,提供行级的性能分析,适合更细致的性能调优。
    实践: 分析报告,识别瓶颈,针对性地优化代码逻辑或数据结构。
  3. 内存分析
    目的: 监控和分析程序运行过程中的内存使用情况,发现内存泄漏或不高效的内存使用模式。
    工具:
    tracemalloc:Python 标准库,可以在程序运行时跟踪内存分配,帮助定位内存增长的原因。
    memory_profiler:第三方库,提供逐行的内存使用统计。
    实践: 定期检查内存使用报告,优化数据结构,及时释放不再使用的资源。
  4. 并发与异步测试
    目的: 验证多线程、多进程或异步IO等并发策略对性能的影响。
    工具: 使用Python的 concurrent.futures、asyncio 模块进行并发编程,配合上述性能测试工具评估效果。
    实践: 设计合理的并发测试场景,确保线程安全,避免竞争条件。
  5. 压力测试与负载测试
    目的: 模拟高并发或大数据量的场景,测试系统在极限条件下的稳定性和响应时间。
    工具:
    locust:开源负载测试工具,支持编写Python脚本模拟用户行为。
    pytest 结合 pytest-asyncio 或 pytest-xdist 插件,进行并发测试。
    实践: 确定测试目标(如请求/秒、并发用户数),持续监控资源使用情况和响应时间,调整系统配置或代码以提高承载能力。
  6. 注意事项
    环境一致性:确保测试环境(操作系统、Python版本、依赖库版本)尽可能与生产环境一致。
    数据代表性:使用接近真实场景的数据集进行测试,以获得有意义的结果。
    避免过早优化:在确定真正的瓶颈之前,避免无目的的性能优化,因为这可能会增加代码复杂度而没有实际收益。
    性能测试是软件开发周期中的重要环节,它能帮助开发者确保应用不仅功能正确,而且运行高效

代码示例

这里就根据自己查找的资料学习几个模块的一些基础用法

timeit

timeit模块是 Python 标准库中的一个组件,专为度量小段代码执行时间而设计。它通过多次运行代码片段并排除首次运行的启动开销(如编译器预热),来提供精确的平均执行时间。timeit 既可以在命令行界面使用,也可以作为 Python 程序的一部分嵌入使用,非常适合快速评估代码性能和比较不同实现方式的效率。

主要特点:
准确性:通过多次重复执行代码来减少随机误差,提供更准确的执行时间测量。
隔离性:自动处理启动成本,比如模块导入或编译,确保只测量目标代码的执行时间。
易用性:支持简单的命令行界面和Python API,便于在各种环境中使用。
灵活性:允许设置执行次数、预置代码(setup code)等参数,适应不同测试需求。

命令行界面使用这里就不多做介绍了,主要记录一下如何在代码中使用。

常用函数
  1. timeit.timeit(stmt, globals=None, number=1000000)
    • stmt: 要计时的代码字符串。
    • globals: 提供执行代码所需的全局命名空间,通常使用 globals()。
    • number: 执行代码的次数,默认是100万次,可以根据需要调整。
import timeit

# 定义要测试的代码
code = """
x = 0
for i in range(1000):
    x += i
"""

# 使用timeit测量代码执行时间
times = timeit.timeit(code, globals=globals(), number=1000)

# 打印执行时间
print(f"Execution time: {times} seconds")

在代码中,我们代用timeit.timeit函数,测试了code变量所代表的代码执行1000次的耗时。

在这里插入图片描述

  1. timeit.repeat(stmt=‘pass’, setup=‘pass’, timer=, repeat=3, number=1000000)
    • stmt: 要计时的代码字符串。
    • setup: 在每次执行 stmt 之前执行的代码字符串,用于初始化。
    • timer: 计时器类型,默认使用最准确的可用计时器。
    • repeat: 重复执行整个测试的次数,返回每次执行的平均时间。
    • number: 每次测试中 stmt 执行的次数。
setup_code = "from math import sqrt"
test_code = "sqrt(100)"

times = timeit.repeat(setup=setup_code, stmt=test_code, repeat=5, number=1000)
print(f"Execution times: {times}")
print(f"Minimum execution time: {min(times)}")

在这里插入图片描述
这个函数稍微复杂一点点。
第一步是先导入模块,第二步编写要执行的代码,第三步就是执行测试函数了。
根据数据结果我们可以看到先输出了五个执行时间,因为在repeat参数的值传入的是5,相当于这个测试执行了五次。number表示每次执行会执行目标代码1000遍。
最后简单输出了一个五个时间里面最小的执行时间。

结尾

性能测试主要量模块,分两次记录,主要是因为第二个模块有点繁琐。

作业

  1. 使用timeit模块对自己编写的代码进行测试。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值