人人都会AI编程

timeit 基准测试

更新时间:2026-07-12

当你需要精确衡量一小段代码的执行时间,而不是整个程序的运行耗时,timeit 模块就是最趁手的工具。它专门用于“微基准测试”,会自动处理垃圾回收干扰、多次运行取平均等细节,让你拿到的不是一个偶然的数值。

为什么不用简单的 time

直接用 time.time() 计时,会受系统负载、CPU 调度、Python 垃圾回收等多种噪声影响,单次测量往往不可靠。timeit 会默认执行上百万次(或指定次数的循环),并多次重复试验来得到一个稳定的统计结果,同时还会自动关闭垃圾回收,确保测量的纯粹性。

两种使用方式

  • 命令行方式:用于临时测试一段简短语句
  python -m timeit "'-'.join(str(n) for n in range(100))"
  

输出示例:10000 loops, best of 5: 22.3 usec per loop
含义:做了多次测试,每次测试会执行过万次目标语句,最终给出最佳的一次平均耗时。

  • Python 接口:更适合在脚本里测试特定函数或逻辑
  import timeit

  def loop_concat():
      result = ''
      for i in range(1000):
          result += str(i)
      return result

  # 用 timeit.Timer 封装待测代码,timeit 会自动选择重复次数
  t = timeit.Timer(loop_concat)
  print(t.timeit(number=1000))  # 执行 1000 次,返回总耗时
  

实用要点

  • 只测你想测的部分:计时语句里不要包含无关的 I/O、网络操作,否则测量的是噪声而非算法耗时。
  • 对比不同写法时控制变量:确保它们作用于相同规模的数据,不然比较毫无意义。
  • 别过度依赖绝对数值:同一份代码在不同机器上耗时可能差好几倍,重点是比较同一环境下两种方案谁的相对耗时更短。
  • 小心死代码优化timeit 可能会因为代码结果未被使用而被优化掉。可以在语句前加 -s 设置环境变量,或确保返回一个有意义的值,避免解释器跳过执行。

常见用法示例

  • 比较字符串拼接方式:
  python -m timeit "s = ''" "for i in range(1000): s += str(i)"
  python -m timeit "lst = [str(i) for i in range(1000)]; ''.join(lst)"
  

输出会清楚显示 join 比循环拼接快得多。

  • 测试列表推导与 map 的性能:
  python -m timeit "[x**2 for x in range(100)]"
  python -m timeit "list(map(lambda x: x**2, range(100)))"
  

timeit 解决的问题很聚焦:让你对一段代码的性能有一个真实、可复现的认知,而不是靠直觉猜测。在实际做性能调优时,先用它找出现象、确认瓶颈,再用 profiler 深入分析具体的位置和调用关系,是最常见的流程。