You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 20:01:03