我在输入模块中创建操作TypeVar
的函数时,遇到了一个问题。我的函数确实可以工作,但我想让它更快,所以我使用了timeit模块来测试一些不同的版本。
然而结果并不是我所期望的。
清除一些潜在的询问:
check_type(object , type)
是一个用来测试一个对象是否对应于一个类型的函数(目前非常耗时)。isTypeVar(type)
测试类型是否为TypeVar。NullType
是一个不能描述对象的类型,所以当用check_type
测试它时,它总是返回False。restrict_TypeVar_for_object(typeVar , object)
是一个函数,我创建它是为了删除typeVar中所有不对应于object的约束。
如何计算函数的时间:
from timeit import timeit
func_version = """..."""
task="""..."""
timeit(task , setups=func_version , number=10_000_000)
下面是我计时的任务(正如你在上面看到的我已经重复了10 000 000次):
Number = int | float
T = TypeVar("T" , int , str , Number)
restrict_TypeVar_for_object(T , 5)
# --> TypeVar("T" , int , Number)
我的测试:
- 第1版:
def restrict_TypeVar_for_object(ty , obj):
if not isTypeVar(ty) : #Just to be sure that ty is a 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) : #Just to be sure that ty is a 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秒
- 第三版:
def restrict_TypeVar_for_object(ty , obj):
if not isTypeVar(ty) : #Just to be sure that ty is a 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
如你所见第二个是最快的。但是我没想到第三个会比另一个慢。坦率地说,我甚至期待它是最快的一个,因为我在这一个做了更少的if语句。
我有两个假设来解释为什么会这样:
- 首先,海象运算符但如果是,为什么第2版是最快的。
第二,我在lCons
的末尾添加了[NullType]
,但我不知道为什么会这么耗时。
1条答案
按热度按时间pprl5pva1#
首先,正如tdelaney指出的,它们执行时间的差异来自于第三版中创建了许多列表:
[c for c in ty.__constraints__ if check_type(obj,c)]
是所有版本通用的。[NullType]
,由lCons + [NullType]
和lCons[:-1]
的级联产生的列表,其专用于第三版本。现在是我问题的第二部分,关于海象运算符的时间消耗。
walrus操作符比简单的分配花费更多的时间,如下面的测试所示:
tsk1重复10 000 000次拍摄:0.7440573999992921秒
tsk2重复10 000 000次拍摄:1.0597749000007752秒
最后,下面是我应该如何在Python中实现我的
restrict_TypeVar_for_object(typeVar , object)
函数:重复10 000 000次需要:**383.57044309999765
然而,正如你所看到的,它仍然需要太多的时间,所以我尝试了海象运算符:
这需要:373.867099199997 s