据我所知,dataclasses.replace(x)和copy.copy(x)做同样的事情,只是它只有在x是dataclass时才起作用,并提供替换成员的能力。然而,我也注意到它的速度大约快了3倍。我现在很好奇为什么copy会慢这么多,以及这两个函数之间是否有其他应该考虑的差异。
import dataclasses
import time
import copy
@dataclasses.dataclass()
class X:
x=1
y=1
z=1
x = X()
start = time.perf_counter()
for _ in range(100000):
a = dataclasses.replace(x)
t1 = time.perf_counter() - start
start = time.perf_counter()
for _ in range(100000):
a = copy.copy(x)
t2 = time.perf_counter() - start
print(t1) # 0.4
print(t2) # 1.2发布于 2021-06-12 04:50:31
正如Chris_Rands在他们的评论中提到的那样,copy.copy有相当多的额外逻辑来处理任意的Python对象-这些额外的逻辑很可能解释了速度上的差异。相比之下,dataclasses.replace只需进行几次检查就可以逃脱惩罚,因为该函数只需要为数据类工作。您可以在dataclasses.py和copy.py的源代码中看到dataclasses.replace比copy.copy (及其调用的函数)简单得多。
如果您查看copy.copy的源代码,您将注意到复制X对象的代码归结为以下内容。
def fastcopy(x):
red = getattr(x,"__reduce_ex__")(4)
return red[0](*red[1])在没有额外检查的情况下,此fastcopy函数的性能似乎与dataclasses.replace相当。下面是我测试的完整代码,以及我得到的时间。
import dataclasses
import time
import copy
def fastcopy(x):
red = getattr(x,"__reduce_ex__")(4)
return red[0](*red[1])
@dataclasses.dataclass()
class X:
x=1
y=1
z=1
x = X()
start = time.perf_counter()
for _ in range(100000):
a = dataclasses.replace(x)
t1 = time.perf_counter() - start
start = time.perf_counter()
for _ in range(100000):
a = fastcopy(x)
t2 = time.perf_counter() - start
print(t1) # 0.1
print(t2) # 0.1https://stackoverflow.com/questions/67941114
复制相似问题