time.time() 单次测量误差大,仅适用于秒级粗略对比;微基准测试应使用 timeit,它禁用 gc、预热解释器、采用高精度计时器,并通过 setup 隔离初始化开销。

用 time.time() 测单次执行时间,误差大到没法信
单次调用 time.time() 前后相减,看似简单,但结果常受系统调度、GC、CPU频率波动干扰。尤其对毫秒级以下的代码,测出来可能是 0.0002s,下一次又变成 0.0015s——这不是代码变慢了,是测量本身在抖。
常见错误现象:time.time() 测 len([1,2,3]) 得到 0.0,误以为“快到不耗时”;实际只是分辨率不够(尤其 Windows 上 time.time() 默认精度约 15ms)。
- 只适合粗略判断“秒级差异”,比如文件读写、网络请求
- 别拿它比对两个
list.append()和deque.append()的快慢 - 如果非要用,至少重复 3–5 次取最小值(不是平均值),因为最小值最接近“纯执行开销”
timeit 才是微基准测试的正确打开方式
timeit 不是“多跑几次求平均”那么简单——它自动禁用 GC、预热解释器、用更高精度计时器(time.perf_counter()),还把待测代码编译成函数反复调用,排除顶层语句开销。
使用场景:比较两种字符串拼接写法、验证缓存是否生效、确认某行表达式有没有意外触发副作用。
- 命令行最省事:
python -m timeit -s "x = list(range(100))" "x[::-1]" - 脚本内推荐
timeit.repeat():比timeit.timeit()更稳,返回多个轮次结果,建议取min()而非mean() - 别漏掉
-s(setup)参数:把初始化代码放进去,否则每次循环都重新建列表,测的是构造成本而非目标操作
示例:
import timeit<br>min_time = min(timeit.repeat(<br> stmt='x[42]',<br> setup='x = list(range(100))',<br> number=100000,<br> repeat=5<br>))<br>print(f'最快一轮:{min_time:.6f}s')
timeit 的坑:setup 写错、number 设太小、没关 GC
很多人跑出“反直觉”结果,八成栽在这三处。
-
setup里不能写带副作用的语句:比如setup='d = {}; d.update({1:2})',会导致每次循环都新建字典并 update,测的根本不是dict.get() -
number太小(如默认 1000000)遇上重操作会超时;太大则可能触发 GC 干扰——建议先试number=10000,看单轮耗时在毫秒级再往上加 - 默认开启 GC,而 GC 时间极不稳定。显式关掉:
timeit.timeit(..., timer=timeit.default_timer, number=..., setup='import gc; gc.disable()'),测完再gc.enable()
复杂点其实在“测什么”,而不是“怎么测”
真正卡住人的,从来不是选 time.time() 还是 timeit,而是没想清楚:你到底想测函数调用开销?还是数据结构遍历?抑或是某段逻辑在真实负载下的表现?
timeit 给你干净、隔离、可复现的数字,但它测不出你线上服务里 Redis 连接池耗尽时的毛刺。微基准测试只是工具链一环,不是答案本身。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











