如何在Python风格的内层循环中避免重复调用高成本函数
方案1:列表推导内置临时变量(无需修改原有逻辑结构)
利用列表推导的多循环语法实现单次计算复用,写法最简洁,和原逻辑结构几乎一致:
paths1= ['a','b','c'] paths2= ['b','c','d'] # 仅对每个y计算一次high_cost_function,结果存入val复用 [any(x.startswith(val) for x in paths1) for y in paths2 for val in [high_cost_function(y)]]
原理:for val in [high_cost_function(y)] 会对每个y仅执行一次函数计算,将结果赋值给val后,内层的any判断全程复用该值,不会重复调用高开销函数。
方案2:提前批量预处理输入(可读性最高)
先把paths2中所有元素的高开销函数计算结果提前生成,再做后续判断,逻辑拆分清晰,便于调试:
paths1= ['a','b','c'] paths2= ['b','c','d'] # 预处理阶段完成所有高开销计算 processed_vals = [high_cost_function(y) for y in paths2] # 后续逻辑直接复用预处理结果 [any(x.startswith(val) for x in paths1) for val in processed_vals]
方案3:函数添加缓存(适合纯函数场景)
如果high_cost_function是无副作用的纯函数(相同输入永远返回相同输出),直接加缓存装饰器即可,原有业务代码无需任何修改:
from functools import lru_cache # 给高开销函数加缓存,相同参数仅计算一次 @lru_cache(maxsize=None) def high_cost_function(p): ... lots of operations... return p # 原有代码完全保留,自动实现结果复用 paths1= ['a','b','c'] paths2= ['b','c','d'] [any(x.startswith(high_cost_function(y)) for x in paths1) for y in paths2]
该方案额外收益:如果该函数在项目其他位置也有重复调用,也会自动复用缓存结果,全局降低性能开销。
内容的提问来源于stack exchange,提问作者Mayday
相关产品推荐
相关产品推荐

