Python timeit函数使用疑问:结果随number增长及首轮性能异常
问题解析与修正
1. 对timeit.timeit()返回值的误解
你搞错了timeit.timeit()的返回值:它返回的是执行number次代码片段的总耗时,不是你以为的“n次单轮中的最优时间”。所以结果随n成比例增长是完全正常的行为,这是核心理解偏差。
2. 第一次运行慢的原因
第一次调用timeit时,Python会产生额外的初始化开销:比如编译代码字符串为代码对象、加载相关内部逻辑的开销。后续调用时这些初始化已经完成,所以耗时会大幅降低,这就是你看到蓝色线条(第一组)慢一个数量级的原因。
3. 修正用法与代码示例
如果你想得到单轮代码的最优/平均耗时,有两种常见方式:
方式一:让timeit自动调整运行次数(推荐)
使用Timer.autorange(),它会自动选择合适的number值,确保总耗时足够稳定,再计算单轮时间:
import timeit import matplotlib.pyplot as plt def get_single_run_time(code): timer = timeit.Timer(code) total_time, run_count = timer.autorange() return total_time / run_count # 测试10轮 single_times = [get_single_run_time("pass") for _ in range(10)] print("单轮pass的最优时间:", min(single_times)) # 对比不同number下的单轮时间 n_values = [10**i for i in range(8)] t_values = [] # 先预热一次,消除初始化开销 timeit.timeit("pass", number=1) for _ in range(10): single_run_times = [timeit.timeit("pass", number=n)/n for n in n_values] t_values.append(single_run_times) for t in t_values: plt.plot(n_values, t) plt.xlabel('单次测试的执行次数') plt.ylabel('单轮"pass"的平均耗时(秒)') plt.title('单轮"pass"执行耗时对比') plt.xscale('log') plt.yscale('log') plt.grid(True, which='both', linestyle='--', linewidth=0.5) plt.show()
方式二:手动计算单轮时间
如果你坚持固定number,只需将总耗时除以number,得到单轮平均时间,再多次运行取最优值即可。
关键修正点
- 增加预热调用:在正式测试前先跑一次
timeit.timeit("pass", number=1),把初始化开销提前消耗掉,避免第一轮结果异常。 - 计算单轮时间:总耗时除以执行次数,得到单轮的平均耗时,这样结果会趋近于代码真实的单轮执行时间,不会随
n线性增长。
内容的提问来源于stack exchange,提问作者Harry van Langen
相关产品推荐
相关产品推荐

