应使用 time.perf_counter() 测量时间间隔,因其单调、高分辨率、跨平台且不受系统时钟调整影响;time.time() 易受 ntp 调整导致负值,time.clock() 已弃用且平台行为不一。

直接用 time.perf_counter() 就行,它返回的是单调、高分辨率的浮点秒数,专为测量时间间隔设计,不受系统时钟调整影响。
为什么不用 time.time() 或 time.clock()?
time.time() 返回的是系统挂钟时间(UTC),可能因 NTP 同步或手动调时跳变,导致测出负值或异常大值;time.clock() 在 Python 3.3+ 已被弃用,且在不同平台语义不一致(Windows 返回进程 CPU 时间,Unix 返回进程时间)。而 perf_counter() 是唯一跨平台、单调、精度通常达纳秒级的计时器。
常见错误现象:
– 程序跑完发现耗时为 -0.000123(time.time() 被系统回拨)
– 多次运行同一段代码,耗时波动剧烈且无规律(混用了 time.process_time(),它只算 CPU 时间,忽略 I/O 等待)
perf_counter() 的基本用法和关键细节
调用两次 perf_counter(),相减即得经过时间。注意:它不保证绝对零点,只保证差值有意义。
- 必须成对调用:一次在开始前,一次在结束后,中间不要被中断或 sleep 干扰(除非你就是要测含等待的总耗时)
- 返回值单位恒为秒,类型是
float,精度取决于系统(Linux/Windows 通常 10–100 纳秒) - 不能用于比较两个不同进程的时间戳,也不能用于生成“当前时刻”,仅用于同一进程内的时间差
- 示例:
import time<br>t0 = time.perf_counter()<br># 你的代码<br>result = sum(range(10**6))<br>t1 = time.perf_counter()<br>print(f"耗时: {t1 - t0:.6f} 秒")
需要重复测量时,别手动写循环——用 timeit 模块
单次测量受系统噪声干扰大(如 GC、调度延迟),真实性能评估需多次运行取最小值或中位数。自己写 for 循环容易漏掉 setup 开销、没禁用 GC,反而引入偏差。
- 简单场景直接用命令行:
python -m timeit -s "import math" "math.sqrt(12345)" - 代码内集成:用
timeit.timeit(),显式传入setup和number,避免把 import 或初始化计入耗时 - 若必须手写循环,请在循环外调用
gc.disable(),测完再gc.enable(),否则 GC 触发会污染结果 - 注意:
timeit默认使用perf_counter(),无需额外指定
在异步或并发环境中要小心上下文切换
perf_counter() 本身线程安全,但如果你在 asyncio 任务里用它测单个 await 表达式,实际测的是“从 await 开始到协程恢复”的总耗时,包含事件循环调度开销,不是纯函数执行时间。
- 测同步函数就老老实实用
perf_counter() - 测 async 函数:用
asyncio.run()包裹后测,或在事件循环内用loop.time()(它底层也基于perf_counter(),但更轻量) - 多线程下每个线程可独立使用
perf_counter(),但不要拿不同线程的时间戳做减法——它们虽同源,但无法保证严格可比
真正难的不是调用函数,而是搞清你到底想测什么:是 CPU 执行时间?端到端响应延迟?还是含磁盘 I/O 的完整流程?选错目标,再高的精度也没意义。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











