为什么Python脚本添加函数后加载速度会显著变慢?
Python拆分为函数后脚本加载卡顿/卡死排查方案
- 第一优先级查无终止的递归/循环调用:新手拆分函数时很容易写出循环调用逻辑,比如函数A内部调用函数B,函数B内部又反过来调用函数A,或者函数自己调用自己时没写退出判断,代码启动后会无限占栈直到内存占满卡死。排查的时候直接在每个函数的第一行加打印日志
print(f"触发函数{函数名}"),运行后看控制台是不是反复刷固定几个函数的日志,就能快速定位问题点。 - 检查重逻辑是不是被放到了全局作用域、或者函数定义阶段就触发执行:正常的函数拆分逻辑是先定义函数,最后在入口块统一调度。如果你把拉取全量历史行情、批量计算技术指标、遍历全量数据集这类耗时操作写在了函数外面的全局位置,脚本一加载就会直接执行这些逻辑,看起来就像加载卡死。另外要注意Python函数默认参数的坑:如果写
def calc_signal(data=get_10y_kline()):这种代码,加载脚本时就会直接执行get_10y_kline()拿返回值当默认参数,根本不会等你调用函数才跑,正确写法是默认参数先设为None,进入函数内部判断参数为空时再执行数据拉取逻辑。 - 检查是否存在重复执行重操作的问题:如果拆分逻辑时把数据拉取、指标计算这类耗时操作放到了被频繁调用的函数内部,又没做缓存,比如每次计算单标的交易信号都重新拉一次全市场历史数据、重算一遍所有周期的指标,会产生巨量冗余IO和计算,短时间占满CPU和内存导致卡顿。这类一次性计算的逻辑要抽到初始化阶段只执行一次,结果作为参数传入下游函数,或者用缓存装饰器存储计算结果避免重复跑。
- 检查是否误写了无限循环:拆分代码时如果把循环的退出条件错放到了循环外部、或者循环内的计数/判断变量没有正确更新,代码会直接进入死循环。排查时可以在循环内部加计数打印,每执行固定次数就输出一次当前进度,很容易就能定位到卡住的循环位置。
- 排查内存异常占用:如果拆分后的函数频繁生成超大的临时数据表、数组,且没有及时回收,或者全局容器(列表、字典)一直在追加数据没有做长度截断,内存占用会持续上涨直到程序被系统强制卡停。可以用
memory_profiler逐行检测函数运行时的内存波动,定位到内存异常上涨的代码段修改即可。
内容的提问来源于stack exchange,提问作者FriesNChicken
相关产品推荐
相关产品推荐

