Python中的timeit模块
时间:2010-05-31 来源:hkebao
Python中的timeit 模块
为一个很短的代码计时都很复杂。处理器有多少时间用于运行这个代码?有什么在后台运行吗?每个现代计算机都在后台运行持续或者间歇的程序。小小的疏 忽可能破坏你的百年大计,后台服务偶尔被 “唤醒” 在最后千分之一秒做一些像查收信件,连接计时通信服务器,检查应用程序更新,扫描病毒,查看是否有磁盘被插入光驱之类很有意义的事。在开始计时测试之前, 把一切都关掉,断开网络的连接。再次确定一切都关上后关掉那些不断查看网络是否恢复的服务等等。
接下来是计时框架本身引入的变化因素。Python 解释器是否缓存了方法名的查找?是否缓存代码块的编译结果?正则表达式呢? 你的代码重复运行时有副作用吗?不要忘记,你的工作结果将以比秒更小的单位呈现,你的计时框架中的小错误将会带来不可挽回的结果扭曲。
Python 社区有句俗语:“Python 自己带着电池。” 别自己写计时框架。Python 2.3 具备一个叫做 timeit 的完美计时工具。
1、timeit 介绍
>>> import timeit
>>> t = timeit.Timer("soundex.soundex('Pilgrim')",
... "import soundex")
>>> t.timeit()
8.21683733547
>>> t.repeat(3, 2000000)
[16.48319309109, 16.46128984923, 16.44203948912]
timeit 模块定义了接受两个参数的 Timer 类。两个参数都是字符串。第一个参数是你要计时的语句,这里你计时的是以'Pilgrim'参数调用 Soundex 函数。传递给 Timer 的第二个参数是为第一个参数语句构建环境的导入语句。从内部讲,timeit 构建起一个独立的虚拟环境,手工地执行建立语句 (导入 soundex 模块),然后手工地编译和执行被计时语句 (调用 Soundex 函数)。 |
|
||
只要有了 Timer 对象,最简单的事就是调用 timeit(), 它调用你的函数一百万次并返回所耗费的秒数。 |
|
||
Timer 对象的另一个主要方法是 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 模块。 |
|
我的理解:
1. t = timeit.Timer(param1,param2)
两个参数都是字符串。
第一个参数是你要计时的语句.
第二个参数是为第一个参数语句构建环境的导入语句
t = timeit.Timer("soundex.soundex('Pilgrim')","import soundex")
计时的语句为: soundex.soundex('Pilgrim') 其中执行需要导入的语句为:import soundex
2. 只要有了 Timer 对象,最简单的事就是调用 timeit(),它调用你的函数一百万次并返回所耗费的秒数。t.timeit()
OK!由第一步我们定义计时命令。在这里面我们做一次压力测试
3、Timer 对象的另一个主要方法是 repeat(), 它接受两个可选参数。第一个参数是重复整个测试的次数,第二个参数是每个测试中调用被计时语句的次数。两个参数都是可选的,它们的默认值分别是 3 和 1000000。repeat() 方法返回以秒记录的每个测试循环的耗时列表。
示例:
t=timeit.Timer("print 'a'");
t.repeat(1,1000) 就能够轻易计算出来执行这个命令一次大概多少时间。