为什么Python dataclass设置frozen=True后实例化速度变慢?
为什么设置
frozen=True后dataclass实例化速度变慢 你对于frozen=True的性能预期是不符合实际实现逻辑的:Python dataclass的冻结特性从来不是为运行效率设计的,它的核心作用是提供不可变语义保障,实现逻辑本身就会带来额外的运行时开销,具体原因如下:
- 当开启
frozen=True时,装饰器会自动为类重写__setattr__和__delattr__方法,两个方法的核心逻辑是拦截所有属性赋值/删除操作,直接抛出FrozenInstanceError,从外部阻止实例属性被修改。 - 类实例化的核心步骤之一就是给实例的各个字段赋初始值。非冻结模式下,
__init__里的赋值直接走C实现的原生对象属性赋值逻辑,没有额外中间层,速度很快。 - 冻结模式下,类自身的
__setattr__是会抛错的,根本没法用来给初始化阶段的属性赋值,因此生成的__init__方法必须绕开自身的拦截逻辑,每次赋值都显式调用object.__setattr__(self, 字段名, 值)完成赋值。这层额外的方法查找、跨类调用、参数传递的开销,在高频实例化场景下就会累积成明显的性能差,刚好和你测试的“耗时翻倍”结果吻合。
你可以通过对比两种模式下生成的__init__方法字节码验证这个差异:非冻结版本的赋值是直接的快速字段存储指令,冻结版本每个字段赋值都多了好几条加载object类、调用__setattr__的指令,执行成本自然高很多。
测试代码如下:
from timeit import timeit setup = """ from dataclasses import dataclass @dataclass(frozen=True) # 切换为False做对照测试 class A: a: int = 1 b: int = 1 """ code = """ obj = A(3, 2) """ print(f"{timeit(code, setup, number=1000_000)=}")
最后补充一点:frozen=True的收益是开发层面的——冻结实例可哈希、能作为字典键使用、不会被业务逻辑意外篡改属性值,从根源上避免一类可变对象相关的bug,不要把它当做性能优化参数使用。
内容的提问来源于stack exchange,提问作者Alex Deft
相关产品推荐
相关产品推荐

