Python分析工具介绍

 众多开发者在日常工作中,往往将大量精力倾注于代码的编写,只要代码能按预期输入输出,便认为任务完成。然而,对于代码的性能及用户端体验,却鲜少有人深入探究。

这种现象在Python开发中尤为显著。许多开发者认为Python语言简洁易懂,无需过多关注优化。

但在我看来,代码的优化工作至关重要。完成编写后,定期回顾、分析和优化代码,是提升个人能力的关键所在。

若开发者仅满足于重复性的编码任务,那无异于单调乏味的搬砖工作。真正的成长与进步,源自对代码的深度思考和分析,这样我们才能不断突破自我,迈向新的高度。

今天,我将以“如何编写更高效的Python代码”为主题,分享一些我在日常开发中使用的实用技巧,希望能为大家带来一些启发。

timeit

这是测试代码运行时长和性能最简单的方法,会用到timeit模块,然后通过命令python -m timeit your_code()就可以输出你这段代码花费的时间。

下面给出一个示例:

python -m timeit "sum(range(1_000_001))"
20 loops, best of 5: 11.5 msec per loop

但是,python -m timeit方法有一个主要缺点,它不会将配置代码与你要进行基准测试的代码分开。

假设你有一个import语句,与从该模块执行函数相比,导入语句需要相对较长的时间。

例如,有下面一段代码:

import numpy
numpy.arange(10)

在基准测试期间,导入将花费大部分时间。 但是我们并不想对导入模块所需的时间进行基准测试。

python -m timeit -s "setup code"

为了将设置代码与基准测试分开,timeit 支持-s参数。

在命令后面传递的任何代码都将被执行,但不会作为基准测试的一部分。

所以我们可以改进上面的代码,这样运行:

python -m timeit -s "import numpy" "numpy.arange(10)"

工具包

从前面可以看出timeit方法比较简单,但是功能也比较简陋。

有些时候,仅仅返回一个数字还不够,如果我们想进一步深入分析,例如,哪个耗时最长?哪个耗时最短?它们之间有什么区别?它们之间的差距有什么影响?等等。

Python是一种工具包非常丰富的编程语言,自然也不缺少这方面的工具包。

这里,就给大家推荐几款我个人比较喜欢的、用于代码基准测试的工具包。

rich-bench

rich-bench这款工具我之前曾在其他的文章中介绍过。

这个小工具可以用不同的代码示例对一组文件进行基准测试,并将结果以清晰的格式显示在表格中。

每个基准将比较两个不同的函数并显示结果的平均值、最小值和最大值,因此我们可以轻松查看结果之间的差异。

pyperf

如果您需要更高级的基准测试工具,那么pyperf一定需要用一下。

它是 Python Performance Benchmark Suite 网站使用的官方工具,这个网站所有 Python 实现的基准测试的权威来源。

pyperf是一个功能丰富的工具,具有许多不同的功能,包括自动校准、检测不稳定结果、跟踪内存使用情况和不同的工作模式等。

让我们来看一个例子。

对于基准测试,使用一个简单但效率低下的函数来计算前 1,000,000 个数字的幂和:sum(n * n for n in range(1_000_001))

这是 timeit 模块的输出:

$ python -m timeit "sum(n * n for n in range(1_000_001))"
5 loops, best of 5: 41 msec per loop

下面是pyperf的输出:

$ python -m pyperf timeit "sum(n * n for n in range(1_000_001))" -o bench.json
.....................
Mean +- std dev: 41.5 ms +- 1.1 ms

结果非常相似,接下来使用-o参数,让 pyperf 将基准测试结果存储在 JSON 文件中,这样就可以分析它们并获得更多信息:

$ python -m pyperf stats bench.json
Total duration: 14.5 sec
Start date: 2022-11-09 18:19:37
End date: 2022-11-09 18:19:53
Raw value minimum: 163 ms
Raw value maximum: 198 ms
​
Number of calibration run: 1
Number of run with values: 20
Total number of run: 21
​
Number of warmup per run: 1
Number of value per run: 3
Loop iterations per value: 4
Total number of values: 60
​
Minimum:         40.8 ms
Median +- MAD:   41.3 ms +- 0.2 ms
Mean +- std dev: 41.5 ms +- 1.1 ms
Maximum:         49.6 ms
​
  0th percentile: 40.8 ms (-2% of the mean) -- minimum
  5th percentile: 40.9 ms (-1% of the mean)
 25th percentile: 41.2 ms (-1% of the mean) -- Q1
 50th percentile: 41.3 ms (-0% of the mean) -- median
 75th percentile: 41.5 ms (+0% of the mean) -- Q3
 95th percentile: 41.9 ms (+1% of the mean)
100th percentile: 49.6 ms (+20% of the mean) -- maximum
​
Number of outlier (out of 40.7 ms..41.9 ms): 3

hyperfine

如果你想对多个Python脚本进行基准测试,hyperfine 会非常好用。

hyperfine 具有与 pyperf 相似的一组功能。 它会自动执行预加载、清除缓存并检测统计异常值。

所有这些,加上漂亮的进度条和颜色,会让输出看起来很漂亮、很清晰。

在一个命令中运行它,它会返回很多有价值的信息,例如平均时间、最小时间和最大时间、标准差、运行次数等:

  • 21
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值