前言
本文是根据python官方教程中标准库模块的介绍,自己查询资料并整理,编写代码示例做出的学习笔记。
根据模块知识,一次讲解单个或者多个模块的内容。
教程链接:https://docs.python.org/zh-cn/3/tutorial/index.html
性能测量
Python中的性能测试主要关注于评估代码执行速度、资源消耗(如内存使用)及扩展性等方面。这有助于开发者识别并优化程序中的瓶颈,确保应用能够高效运行。
水平有限,讲一些关键概念和实践方法,简单写点代码运行一下。
- 基准测试 (Benchmarking)
目的: 基准测试是评估代码片段或整个应用程序在特定条件下的执行性能,通常用来比较不同实现方式的效率。
工具: 使用 timeit 模块进行简单的重复执行计时,或者 pytest-benchmark 这样的第三方库进行更复杂的测试场景。
实践: 设定明确的测试环境(如数据集大小、硬件配置),确保测试结果可复现和比较。 - 性能剖析 (Profiling)
目的: 细致地分析代码中各个部分的执行时间,找出耗时最长的部分(热点)。
工具:
cProfile:Python 标准库中的性能剖析器,提供函数级别的性能报告。
line_profiler:第三方库,提供行级的性能分析,适合更细致的性能调优。
实践: 分析报告,识别瓶颈,针对性地优化代码逻辑或数据结构。 - 内存分析
目的: 监控和分析程序运行过程中的内存使用情况,发现内存泄漏或不高效的内存使用模式。
工具:
tracemalloc:Python 标准库,可以在程序运行时跟踪内存分配,帮助定位内存增长的原因。
memory_profiler:第三方库,提供逐行的内存使用统计。
实践: 定期检查内存使用报告,优化数据结构,及时释放不再使用的资源。 - 并发与异步测试
目的: 验证多线程、多进程或异步IO等并发策略对性能的影响。
工具: 使用Python的 concurrent.futures、asyncio 模块进行并发编程,配合上述性能测试工具评估效果。
实践: 设计合理的并发测试场景,确保线程安全,避免竞争条件。 - 压力测试与负载测试
目的: 模拟高并发或大数据量的场景,测试系统在极限条件下的稳定性和响应时间。
工具:
locust:开源负载测试工具,支持编写Python脚本模拟用户行为。
pytest 结合 pytest-asyncio 或 pytest-xdist 插件,进行并发测试。
实践: 确定测试目标(如请求/秒、并发用户数),持续监控资源使用情况和响应时间,调整系统配置或代码以提高承载能力。 - 注意事项
环境一致性:确保测试环境(操作系统、Python版本、依赖库版本)尽可能与生产环境一致。
数据代表性:使用接近真实场景的数据集进行测试,以获得有意义的结果。
避免过早优化:在确定真正的瓶颈之前,避免无目的的性能优化,因为这可能会增加代码复杂度而没有实际收益。
性能测试是软件开发周期中的重要环节,它能帮助开发者确保应用不仅功能正确,而且运行高效
代码示例
这里就根据自己查找的资料学习几个模块的一些基础用法
timeit
timeit
模块是 Python 标准库中的一个组件,专为度量小段代码执行时间而设计。它通过多次运行代码片段并排除首次运行的启动开销(如编译器预热),来提供精确的平均执行时间。timeit 既可以在命令行界面使用,也可以作为 Python 程序的一部分嵌入使用,非常适合快速评估代码性能和比较不同实现方式的效率。
主要特点:
准确性:通过多次重复执行代码来减少随机误差,提供更准确的执行时间测量。
隔离性:自动处理启动成本,比如模块导入或编译,确保只测量目标代码的执行时间。
易用性:支持简单的命令行界面和Python API,便于在各种环境中使用。
灵活性:允许设置执行次数、预置代码(setup code)等参数,适应不同测试需求。
命令行界面使用这里就不多做介绍了,主要记录一下如何在代码中使用。
常用函数
- 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次的耗时。
- 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遍。
最后简单输出了一个五个时间里面最小的执行时间。
结尾
性能测试主要量模块,分两次记录,主要是因为第二个模块有点繁琐。
作业
- 使用timeit模块对自己编写的代码进行测试。