Python中TypeVar处理函数的三个版本执行时间差异原因分析
处理TypeVar约束过滤函数的性能异常问题
问题背景
编写操作typing模块中TypeVar的函数时遇到性能瓶颈,函数功能正常但希望提升运行速度,使用timeit模块测试不同版本后,结果与预期不符。
相关定义
check_type(object, type):校验对象是否匹配指定类型,当前本身耗时较高isTypeVar(type):判断输入是否为TypeVar类型NullType:无法匹配任何对象的特殊类型,与check_type配合使用时始终返回Falserestrict_TypeVar_for_object(typeVar, object):自定义函数,用于移除TypeVar中与目标对象不匹配的所有约束
测试方法
使用Python的timeit模块进行性能测试,代码模板如下:
from timeit import timeit func_version = """...""" task="""...""" timeit(task , setup=func_version , number=10_000_000)
测试场景(重复执行1000万次)
测试用例代码:
Number = int | float T = TypeVar("T", int, str, Number) restrict_TypeVar_for_object(T, 5) # --> 预期返回 TypeVar("T", int, Number)
测试结果
第一版实现
def restrict_TypeVar_for_object(ty , obj): if not isTypeVar(ty) : # 确保输入是TypeVar raise ValueError ('Expected a TypeVar as an argument') if not ty.__constraints__ : return type(obj) lCons=[cons for cons in ty.__constraints__ if check_type(obj , cons)] return (TypeVar(ty.__name__ , *lCons) if len(lCons)>1 else lCons[0] if lCons else NullType)
耗时:378.5483768 s
第二版实现
def restrict_TypeVar_for_object(ty , obj): if not isTypeVar(ty) : # 确保输入是TypeVar raise ValueError ('Expected a TypeVar as an argument') if not ty.__constraints__ : return type(obj) return (TypeVar(ty.__name__ , *lCons) if len(lCons:=[cons for cons in ty.__constraints__ if check_type(obj , cons)])>1 else lCons[0] if lCons else NullType)
耗时:376.9706139 s
第三版实现
def restrict_TypeVar_for_object(ty , obj): if not isTypeVar(ty) : # 确保输入是TypeVar raise ValueError ('Expected a TypeVar as an argument') if not ty.__constraints__ : return type(obj) return (TypeVar(ty.__name__ , *lCons[:-1]) if len(lCons:=[c for c in ty.__constraints__ if check_type(obj,c)]+[NullType]) > 2 else lCons[0])
耗时:391.5145658000001 s
疑问与分析
第二版是三个版本中最快的,但第三版原本因条件判断更少被预期为最快,结果耗时反而大幅增加。目前有两个猜测:
- 海象运算符的影响?但第二版同样使用了海象运算符却更快,该猜测不成立。
- 向列表追加
[NullType]的操作导致耗时增加?暂不清楚该操作为何会带来如此大的性能开销。
内容的提问来源于stack exchange,提问作者JSaur
相关产品推荐
相关产品推荐

