返回介绍

18.2. 使用 timeit 模块

发布于 2019-09-14 13:31:00 字数 3413 浏览 802 评论 0 收藏 0

18.2. 使用 timeit 模块

关于 Python 代码优化你需要知道的最重要问题是,决不要自己编写计时函数。

为一个很短的代码计时都很复杂。 处理器有多少时间用于运行这个代码? 有什么在后台运行吗? 每个现代计算机都在后台运行持续或者间歇的程序。 小小的疏忽可能破坏你的百年大计,后台服务偶尔被 “唤醒” 在最后千分之一秒做一些像查收信件,连接计时通信服务器,检查应用程序更新,扫描病毒,查看是否有磁盘被插入光驱之类很有意义的事。 在开始计时测试之前,把一切都关掉,断开网络的连接。再次确定一切都关上后关掉那些不断查看网络是否恢复的服务等等。

接下来是计时框架本身引入的变化因素。 Python 解释器是否缓存了方法名的查找? 是否缓存代码块的编译结果? 正则表达式呢? 你的代码重复运行时有副作用吗? 不要忘记,你的工作结果将以比秒更小的单位呈现,你的计时框架中的小错误将会带来不可挽回的结果扭曲。

Python 社区有句俗语: “Python 自己带着电池。” 别自己写计时框架。 Python 2.3 具备一个叫做 timeit 的完美计时工具。

例 18.2. 介绍 timeit

如果您还没有下载本书附带的例子程序, 可以 下载本程序和其他例子程序。

>>> import timeit
>>> t = timeit.Timer("soundex.soundex('Pilgrim')",
...     "import soundex")   1
>>> t.timeit()              2
8.21683733547
>>> t.repeat(3, 2000000)    3
[16.48319309109, 16.46128984923, 16.44203948912]
1timeit 模块定义了接受两个参数的 Timer 类。两个参数都是字符串。 第一个参数是你要计时的语句,这里你计时的是以'Pilgrim'参数调用 Soundex 函数。 传递给 Timer 的第二个参数是为第一个参数语句构建环境的导入语句。 从内部讲, timeit 构建起一个独立的虚拟环境, 手工地执行建立语句(导入 soundex 模块),然后手工地编译和执行被计时语句(调用 Soundex 函数)。
2一旦有了 Timer 对象,最简单的事就是调用 timeit(),它调用你的函数一百万次并返回所耗费的秒数。
3Timer 对象的另一个主要方法是 repeat(), 它接受两个可选参数。 第一个参数是重复整个测试的次数,第二个参数是每个测试中调用被计时语句的次数。 两个参数都是可选的,它们的默认值分别是 3 和 1000000。 repeat() 方法返回以秒记录的每个测试循环的耗时列表。
提示
你可以在命令行使用 timeit 模块来测试一个已存在的 Python 程序,而不需要修改代码。在 http://docs.python.org/lib/node396.html 查看文档中关于命令行选项的内容。

注意 repeat() 返回一个时间列表。 由于 Python 计时器使用的处理器时间的微小变化(或者那些你没办法根除的可恶的后台进程),这些时间中几乎不可能出现重复。你的第一想法也许是说:“让我们求平均值获得真实的数据。”

事实上,那几乎是确定错误的。 你的代码或者 Python 解释器的变化可能缩短耗时,那些没办法去处的可恶后台进程或者其他 Python 解释器以外的因素也许另耗时延长。 如果计时结果之间的差异超过百分之几,太多的可变因素使你没法相信结果,如果不是这样则可以取最小值而丢弃其他结果。

Python 有一个方便的 min 函数可以把输入的列表返回成最小值:

>>> min(t.repeat(3, 1000000))
8.22203948912
提示
timeit 模块只有在你知道那段代码需要优化时使用。 如果你有一个很大的 Python 程序并且不知道你的性能问题所在,到 查看 hotshot 模块。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文