单次测量用 timeit.timeit(),但易受系统负载干扰;评估稳定性或排除异常值必须用 timeit.repeat(),它默认执行3组、每组1000000次,返回列表可取min()最可靠。

timeit.timeit() 和 timeit.repeat() 怎么选
单次测量用 timeit.timeit(),但结果容易受瞬时系统负载干扰;想评估稳定性或排除异常值,必须用 timeit.repeat() —— 它默认执行 3 组,每组调用 number 次(默认 1000000),返回列表,你取 min() 最可靠。
常见错误是直接信 timeit.timeit() 的一次结果,尤其在笔记本或虚拟机上,CPU 频率波动、后台进程都可能让误差超 20%。
-
repeat=5, number=100000比默认更稳妥,适合中等耗时代码 - 如果函数执行很快(number 到 10⁶ 或更高,避免计时器本身开销占比过大
- 用
repeat()后别取平均值,取min()—— 这最接近“纯函数执行时间”,避开上下文干扰
setup 参数写错会导致 benchmark 失效
setup 不只是导入语句,它决定测试环境是否干净。漏掉变量预定义、错用字符串拼接、忘记 import,都会让 timeit 报 NameError 或测到无关开销。
例如测 list.append(),如果在 stmt 里每次新建 list:stmt='l = []; l.append(1)',实际测的是创建 list + append,不是 append 本身。
立即学习“Python免费学习笔记(深入)”;
95Shop可以免费下载使用,是一款仿醉品商城网店系统,内置SEO优化,具有模块丰富、管理简洁直观,操作易用等特点,系统功能完整,运行速度较快,采用ASP.NET(C#)技术开发,配合SQL Serve2000数据库存储数据,运行环境为微软ASP.NET 2.0。95Shop官方网站定期开发新功能和维护升级。可以放心使用! 安装运行方法 1、下载软件压缩包; 2、将下载的软件压缩包解压缩,得到we
- 正确做法:在
setup中初始化数据,stmt只写待测操作,如setup='l = []',stmt='l.append(1)' - 多行 setup?用三引号或
;连接,但注意换行符不被支持,setup='import math; x = 123'是安全的 - 避免在
setup中执行耗时操作(如读文件、生成大列表),否则会污染计时结果
命令行调用 timeit 时路径和作用域容易出错
用 python -m timeit 最方便,但要注意当前工作目录和 Python 模块搜索路径 —— 它不自动包含当前目录,-m 模式下也无法直接 import 本地 .py 文件。
典型报错:ModuleNotFoundError: No module named 'myutils',哪怕 myutils.py 就在当前文件夹。
- 解决方法一:加
-p .(Python 3.11+)或临时改PYTHONPATH=. - 解决方法二:把待测代码写成字符串传入,用
-s写 setup,如python -m timeit -s "from math import sqrt" "sqrt(144)" - 别在命令行里用相对路径导入模块;也别依赖
__file__或os.getcwd()——timeit的执行上下文不保证与你预期一致
timeit.Timer 实例比函数调用更灵活,但要手动管理命名空间
当你需要反复测多个 stmt、共享同一 setup,或想控制 globals/locals 时,timeit.Timer 是唯一选择。但它不会自动帮你隔离变量,locals 冲突或 globals 覆盖很常见。
比如你在 globals() 里传了 {'x': 10},又在 stmt 里写 x += 1,就会报 UnboundLocalError —— 因为 Python 认为 x 是局部变量,但首次引用前未赋值。
- 安全做法:用独立字典传
globals,且确保所有变量都在里面初始化,如g = {'x': 10}; t = timeit.Timer('x += 1', globals=g) - 避免混用
globals和locals;优先只用globals,locals在闭包或动态作用域下行为难预测 - 如果 stmt 依赖类或函数定义,全写进
setup字符串里,别指望从外部 globals 自动带入









