You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python装饰器计时结果与直接调用计时结果不一致原因咨询

装饰器计时与直接计时结果不一致的原因

代码

from time import time
def speed_test(func):
    def wrapper(*args, **kwargs):
        start = time()
        func(*args, **kwargs)
        end = time() - start
        print(f"Execution time is: {end:.17f}s  # Decorator")
    return wrapper
@speed_test 
def sorting(L):
    L.sort() # For example
    
def sorting_1(L1):
    L1.sort()
    
T = [10, 5, 3, 1, 0]
L = T.copy()

sorting(T)

a = time()
sorting_1(L)
b = time() - a
print(f"Execution time is: {b:.17f}s  # Main")

预期输出

Execution time is: 0.00000977516174316s  # Decorator
Execution time is: 0.00000977516174316s  # Main

实际输出

Execution time is: 0.00000977516174316s  # Decorator
Execution time is: 0.00000572204589844s  # Main

差异原因

核心问题是两次排序的列表状态完全不同:

  • 调用sorting(T)时,T是未排序的原始列表[10,5,3,1,0],L.sort()需要完成完整的排序操作,耗时较长。
  • 执行完sorting(T)后,T已经被排序为[0,1,3,5,10],而L = T.copy()复制的是这个已完全有序的列表。后续调用sorting_1(L)时,L.sort()处理的是有序序列,Python内置的Timsort算法对完全有序的序列有极致优化,几乎不需要执行交换操作,因此耗时远低于第一次排序。

装饰器的wrapper函数会带来极其微小的调用开销,但这不是本次差异的主要原因,核心还是列表是否有序的问题。

如果要验证这个结论,可以做两个调整:

  • 调换两个函数的调用顺序,先调用sorting_1(L)再调用sorting(T),会看到第一次计时更长,第二次更短;
  • 给L重新赋值为未排序的列表,比如L = [10,5,3,1,0].copy(),此时两次计时结果会基本一致。

内容的提问来源于stack exchange,提问作者Ghoudiy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 01:35:24