当前位置: 首页 > news >正文

Python 高手编程系列三千三百八十八:微观分析

当找到慢速函数时,有时需要进行更多的测试工作,只测试程序的一部分。通过在速
度测试中手动检测一部分代码来完成测试。
例如,可以从装饰器使用 cProfile 模块,如下所示:

import tempfile, os, cProfile, pstats
def profile(column=‘time’, list=5):
… def _profile(function):
… def __profile(*args, **kw):
… s = tempfile.mktemp()
… profiler = cProfile.Profile()
… profiler.runcall(function,args, **kw)
… profiler.dump_stats(s)
… p = pstats.Stats(s)
… p.sort_stats(column).print_stats(list)
… return __profile
… returnprofile

from myapp import main
@profile(‘time’, 6)
… def main_profiled():
… return main()

main_profiled()
Mon Apr 4 22:01:01 2016 /tmp/tmpvswuovz

1207 function calls in 8.243 seconds
Ordered by: internal time
List reduced from 7 to 6 due to restriction <6>
Ncalls tottime percall cumtime percall file:lineno(function)
602 8.241 0.014 8.241 0.014 {built-in method sleep}
400 0.001 0.000 4.026 0.010 myapp.py:5(medium)
2 0.001 0.000 8.243 4.121 myapp.py:13(heavy)
200 0.000 0.000 0.213 0.001 myapp.py:9(light)
1 0.000 0.000 8.243 8.243 myapp.py:21(main)
1 0.000 0.000 8.243 8.243 :1(main_profiled)
from myapp import light
stats = profile()(light)
stats()
Mon Apr 4 22:01:57 2016 /tmp/tmpnp_zk7dl
3 function calls in 0.001 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall file:lineno(function)
1 0.001 0.001 0.001 0.001 {built-in method sleep}
1 0.000 0.000 0.001 0.001 myapp.py:9(light)
这种方法允许测试应用程序的一部分,并锐化统计输出。但在这个阶段,有一个被调
用者列表可能不是很有用,因为已经指出该函数需要进行优化。唯一令人关注的信息是知
道它有多快,然后增强它。
timeit 提供一种简单的方法来测量小代码片段的执行时间,它使用主机系统提供的
最佳底层计时器(time.time 或 time.clock),从而更好地满足这种需要,如下所示:
from myapp import light
import timeit
t = timeit.Timer(‘main()’)
t.timeit(number=5)
10000000 loops, best of 3: 0.0269 usec per loop
10000000 loops, best of 3: 0.0268 usec per loop
10000000 loops, best of 3: 0.0269 usec per loop
10000000 loops, best of 3: 0.0268 usec per loop
10000000 loops, best of 3: 0.0269 usec per loop
5.6196951866149902
该模块可以被重复调用,并且面向测试隔离的代码片段。这在应用程序上下文之外非常有用,在命令提示符中,例如,在现有应用程序中使用不是很方便。
但是应该谨慎使用 timeit 的结果。这是一个非常好的工具,它可以客观地比较两段
短代码,但它也会让你很容易犯下危险的错误,这将导致令人困惑的结论。这里,例如,
通过 timeit 模块对两个无害的代码片段进行比较,它可以使你认为通过加法的字符串连
接比 str.join()方法更快:
$ python3 -m timeit -s ‘a = map(str, range(1000))’ ‘“”.join(a)’
1000000 loops, best of 3: 0.497 usec per loop
$ python3 -m timeit -s ‘a = map(str, range(1000)); s=“”’ ‘for i in a: s
+= i’
10000000 loops, best of 3: 0.0808 usec per loop
从第 2 章开始,我们知道通过加法连接字符串不是一个好的模式。尽管有一些针对这
种用法设计的一些较小的 CPython 微优化,它最终会导致二次的运行时间。问题在于
timeit(命令行中-s 参数)设置参数的细微差别,以及 Python 3 中的范围如何工作。我
不会讨论问题的细节,但会把它留给你作为一个练习。总之,在 Python 3 中,这是正确的
比较使用加法和 str.join()连接字符串的方法,如下所示:
$ python3 -m timeit -s ‘a = [str(i) for i in range(10000)]’ ‘s=“”.
join(a)’
10000 loops, best of 3: 128 usec per loop
$ python3 -m timeit -s ‘a = [str(i) for i in range(10000)]’ ’
s = “”
for i in a:
s += i

1000 loops, best of 3: 1.38 msec per loop
测量 Pystones
当测量执行时间时,结果取决于计算机硬件。为了能够产生通用测量,最简单的方法
测量固定序列的代码基准速度,并计算出它的比率。由此,函数所花费的时间可以转换为
一个比较通用的值,可以在任何计算机上比较。
Python 在其 test 包中提供了一个基准测试工具,用于测量一个精选的操作序列的持
续时间。结果是每秒钟计算机能够执行的 pystones 数量,在现代硬件上通常约为一秒,
如下所示:
from test import pystone
pystone.pystones()
(1.0500000000000007, 47619.047619047589)
该比率可用于将分析的持续时间转换为 pystones 的数量:
from test import pystone
benchtime, pystones = pystone.pystones()
def seconds_to_kpystones(seconds):
… return (pystones
seconds) / 1000


seconds_to_kpystones(0.03)
1.4563106796116512
seconds_to_kpystones(1)
48.543689320388381
seconds_to_kpystones(2)
97.087378640776762
seconds_to_kpystones 返回千个 ρystones 的数量。如果你想编写一些速度断言,
这个转换可以包含在你的测试中。
拥有 pystones 将允许你在测试中使用此装饰器,以便于你在执行时间上设置断言。
这些测试可以在任何计算机上运行,并让开发人员避免速度回归。当应用程序的一部分已
优化时,他们将能够在测试中设置其最大执行时间,并确保它不会被进一步的更改所破坏。
这种方法当然不是理想的并且 100%准确的,但是它至少比以硬编码的执行时间断言更好,
这些断言是以秒表示的原始值。

http://www.jsqmd.com/news/1005009/

相关文章:

  • 华为ENSP模拟实战:手把手教你从零搭建一个带灾备的企业网(附完整配置包)
  • 禹州装修公司怎么选?一品装饰工地可随时看 - 猜不透的vv
  • 2026普洱旧金铂银回收黄金回收高信誉门店汇总 5 家线下实体回收商家实地评测与联络渠道整理 - 中业金奢再生回收中心
  • 贺州市2026年上门黄金回收白银回收铂金回收测评,五家全城可上门实体店整理 - 干豆腐啊
  • 2026武汉名包回收天花板:六家门店实测,高价变现不踩雷 - 讯息早知道
  • ComfyUI 部署 FLUX.1 GGUF 量化模型完整技术教程
  • 2026年热门手机阅读器大揭秘:哪个才具备个性化设置?
  • 2026杭州余杭伯爵出手|暗藏猫腻,不少人在这里吃了亏 - 逸程
  • GEO科普系列专题:第五期——权威信源建设与E-E-A-T原则:让AI“信任”你的品牌
  • 从寄存器堆到指令存储器:手把手教你用Verilog在头歌平台搭建一个简易CPU核心
  • Cesium项目实战:用Entity实现一个可交互的动态数据看板(附完整代码)
  • FUXA工业可视化平台:现代化SCADA/HMI系统的开源解决方案
  • 滨州市2026年黄金回收白银回收铂金回收变卖,5 家靠谱贵金属门店实地测评汇总 - 凯撒是大帝
  • 阆中汽车贴膜选购全攻略:膜材科普与实用避坑指南 - 百航
  • 2026南京奢侈品黄金回收大额交易深度评测 - 奢侈品回收
  • 网盘限速终结者:9大平台直链下载神器LinkSwift实战指南
  • CH32V307 SPI主从机通信避坑指南:从单机发送到双机互传的完整配置流程
  • 别再只会调频率了!用运放搭波形发生器,手把手教你搞定占空比和幅值(附完整电路图)
  • 如何快速配置Unity游戏自动翻译插件:XUnity.AutoTranslator完全指南
  • 青岛崂山区商圈实测:金价913元 克回收如何避坑 - 专业黄金回收
  • LabVIEW层叠式顺序结构隐藏技巧:如何优雅管理多步骤仪器控制与状态切换
  • 贵阳花溪区商圈实测:黄金回收价格与避坑指南 - 专业黄金回收
  • 潮州市2026年黄金回收白银回收铂金回收变卖,5 家靠谱贵金属门店实地测评汇总 - 凯撒是大帝
  • 【2027最新】基于SpringBoot+Vue的车辆管理系统管理系统源码+MyBatis+MySQL
  • 2026年热门微辣酱香商用麻辣炒料实测指南:餐饮开店选料不踩雷 - 麻辣烫酱料
  • 大模型编排层为何正在消失?从Anthropic架构坍缩看LLM中间件演进
  • “安能大件物流介绍”、“安能大件物流”、“安能物流介绍”、“安能物流最新发展状况” - 安互工业信息
  • 2026娄底旧金铂银回收黄金回收高信誉门店汇总 5 家线下实体回收商家实地评测与联络渠道整理 - 中业金奢再生回收中心
  • 卡尔曼滤波(Kalman Filter, 简称 KF)是一种高效的递归滤波算法,用于在噪声环境中从一系列不完全或不确定的测量数据中估计动态系统的状态
  • 魔兽争霸III现代化改造终极指南:3分钟解决宽屏、卡顿与地图加载难题