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

函数在脚本中的位置变更导致执行时长变化的原因及解决方法

问题解答

1. 计时结果受函数位置影响的原因

  • 解释器预热与系统资源波动:Python解释器启动后会逐步完成字节码编译缓存、底层状态优化等预热操作。如果函数放在脚本末尾,执行它时前面的代码已经占用了部分CPU缓存、内存资源,甚至触发了垃圾回收(GC),导致单次计时结果偏高。
  • 首次调用的额外开销:你的inits_lstcm_slice_regex包含正则操作,re模块的正则编译是首次调用时才完成的,这部分初始化耗时会被计入第一次执行的计时。如果函数放在末尾,刚好是它的首次执行被统计;放在开头时,系统资源更空闲,后续函数的执行不会干扰这次初始化的计时结果。
  • 短时间连续测试的调度干扰:连续执行多个性能测试时,后面的测试可能遇到CPU调度切换、内存页缺失等系统层面的波动,进一步放大计时误差。

2. 能否复现该现象

可以复现。尤其是当测试函数包含正则编译、大量字符串操作这类有首次调用开销的逻辑,且测试循环次数少、计时精度不足时,重现概率会很高(和你提到的90%左右一致)。比如在普通CPython环境下,把带正则的函数放在脚本末尾,首次执行的耗时会明显高于放在开头的情况。

3. 修改代码实现可靠性能对比的方法

  • 预执行预热:正式计时前,先调用每个测试函数至少一次,消除首次调用的初始化开销(比如正则编译、字节码首次编译):
    # 预执行所有测试函数,消除首次调用开销
    inits_lstcm_slice_regex()
    other_func1()
    other_func2()
    
  • 增加循环次数取平均:单次执行的计时误差大,通过多次循环取平均降低波动。比如每个函数执行1000次以上,用总耗时除以循环次数得到平均耗时。
  • 使用timeit模块:timeit会自动处理预热、多次循环,给出更稳定的统计结果,比手动用time.time()更可靠:
    import timeit
    
    def inits_lstcm_slice_regex():
        # 你的函数逻辑
        pass
    
    # 执行10000次循环,取3次测试的最佳结果
    total_time = timeit.timeit(inits_lstcm_slice_regex, number=10000)
    print(f"平均耗时: {total_time/10000:.6f} 秒")
    
  • 随机化测试顺序:打乱测试函数的执行顺序,重复多次测试后取平均,消除固定顺序带来的系统资源影响:
    import random
    
    test_funcs = [inits_lstcm_slice_regex, other_func1, other_func2]
    # 重复测试5次
    for _ in range(5):
        random.shuffle(test_funcs)
        for func in test_funcs:
            # 执行计时逻辑
            pass
    
  • 临时禁用垃圾回收:测试期间禁用GC,避免GC触发导致的耗时波动,测试结束后再恢复:
    import gc
    
    gc.disable()
    # 执行所有计时测试
    gc.enable()
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 15:10:23