python 标准库 timeit
每日一词:
Pneumonia
n 肺炎
2019 Novel coronavirus (2019-nCoV),
世界卫生组织定义, 又名武汉冠状病毒(Wuhan coronavirus)、武汉肺炎(Wuhan pneumonia)冠状病毒属的病毒是具外套膜(envelope)
例句:
The doctor diagnosed the illness as pneumonia .
医生诊断这病为肺炎。The doctor has cured her of pneumonia .
大夫把她的肺炎看好了。Fatalities usually come from pneumonia .
通常肺炎可引起死亡。
源码
源码: Lib/timeit.py
该模块提供了一种简单的方法来计算一小段 Python 代码的耗时。它有 命令行界面 以及一个 可调用 方法。它避免了许多用于测量执行时间的常见陷阱。另见 Tim Peters 对 O’Reilly 出版的 Python Cookbook 中“算法”章节的介绍。
基本实例
以下示例显示了如何使用 命令行界面 来比较三个不同的表达式:
1 | $ python3 -m timeit '"-".join(str(n) for n in range(100))' |
这可以通过 Python 接口 实现
1 | import timeit |
从 Python 接口 还可以传出一个可调用对象:
1 | lambda: "-".join(map(str, range(100))), number=10000) timeit.timeit( |
但请注意 timeit()
仅在使用命令行界面时会自动确定重复次数。 在 示例 一节你可以找到更多的进阶示例。
python接口
该模块定义了三个便利函数和一个公共类:
timeit.timeit
(stmt=’pass’, setup=’pass’, timer=, number=1000000, globals=None)timeit.repeat
(stmt=’pass’, setup=’pass’, timer=, repeat=5, number=1000000, globals=None)timeit.default_timer
()- class
timeit.Timer
(stmt=’pass’, setup=’pass’, timer=, globals=None)timeit
(number=1000000)autorange
(callback=None)repeat
(repeat=5, number=1000000)print_exc
(file=None)
命令行界面
从命令行调用程序时,使用以下表单:
1 | python -m timeit [-n N] [-r N] [-u U] [-s S] [-h] [statement ...] |
如果了解以下选项:
-n N, --number=N
执行 ‘语句’ 多少次
-r N, --repeat=N
重复计时器的次数(默认为5)
-s S, --setup=S
最初要执行一次的语句(默认为
pass
)`-p, –process
1
2
3
4
5
6
7
8
测量进程时间,而不是 wallclock 时间,使用 [`time.process_time()`](https://docs.python.org/zh-cn/3.8/library/time.html#time.process_time) 而不是 [`time.perf_counter()`](https://docs.python.org/zh-cn/3.8/library/time.html#time.perf_counter) ,这是默认值*3.3 新版功能.*
- `-u````, ``--unit``=U`
指定定时器输出的时间单位;可以选择 nsec,usec,msec或sec*3.5 新版功能.*
- `-v````, ``--verbose打印原始计时结果;重复更多位数精度
-h```
,--help`
打印一条简短的使用信息并退出
可以通过将每一行指定为单独的语句参数来给出多行语句;通过在引号中包含参数并使用前导空格可以缩进行。多个 -s
选项的处理方式相似。
如果 -n
未给出,则通过尝试10的连续幂次来计算合适数量的循环,直到总时间至少为 0.2 秒。
default_timer()
测量可能受到在同一台机器上运行的其他程序的影响,因此在需要精确计时时最好的做法是重复几次计时并使用最佳时间。 -r
选项对此有利;在大多数情况下,默认的 5 次重复可能就足够了。 你可以使用 time.process_time()
来测量CPU时间。
执行 pass 语句会产生一定的基线开销。这里的代码不会试图隐藏它,但你应该知道它。可以通过不带参数调用程序来测量基线开销,并且Python版本之间可能会有所不同。
实例
可以提供一个在开头只执行一次的 setup 语句:
1 | $ python -m timeit -s 'text = "sample string"; char = "g"' 'char in text' |
1 | import timeit |
使用 Timer
类及其方法可以完成同样的操作:
1 | import timeit |
以下示例显示如何计算包含多行的表达式。 在这里我们对比使用 hasattr()
与 try
/except
的开销来测试缺失与提供对象属性:
1 | $ python -m timeit 'try:' ' str.__bool__' 'except AttributeError:' ' pass' |
1 | import timeit |
要让 timeit
模块访问你定义的函数,你可以传递一个包含 import 语句的 setup 参数:
1 | def test(): |
另一种选择是将 globals()
传递给 globals 参数,这将导致代码在当前的全局命名空间中执行。这比单独指定 import 更方便
1 | def f(x): |