You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

多父类继承的属性读取性能影响及性能衰减趋势探究

多父类继承的属性读取性能影响及性能衰减趋势探究

我一直在研究一种超宽泛的继承结构对性能的影响,具体的测试步骤如下:

  • 先准备260个不同的属性名,范围是a0z9
  • 创建260个类,每个类仅包含一个唯一命名的属性;再创建一个继承自这260个类的聚合类
  • 创建130个类,每个类包含2个唯一命名的属性;同样创建一个继承自这130个类的聚合类
  • 按照这个逻辑继续拓展测试:52个类(每个含5个属性)、26个类(每个含10个属性),以及一个包含全部260个属性的单一类
  • 为上述5个类各创建一个实例,然后分别测量读取并累加所有260个属性的耗时

我完成了250万次属性读取的平均性能测试,测试过程中还打乱了不同的读取顺序,最终得到的结果如下:

From260: 2.48
 From130: 1.55
  From52: 1.22
  From26: 1.15
AllInOne: 1.00

这些数据看起来能用线性回归拟合,但实际上并不完全匹配。而且不管测试规模、读取顺序怎么调整,这个性能关联关系都稳定存在。

![线性关系拟合图]

后来我尝试用二次多项式或者指数模型去拟合数据,贴合度有所提升,但依然没有达到完全清晰匹配的程度。

![二次/指数拟合对比图]

现在我有个核心疑问:当父类的数量大幅增加时,性能衰减会呈现线性趋势,还是非线性趋势?


为了进一步探究这个问题,我更新了测试代码,覆盖了更多不同的子类组合(最多到2310个父类):

from time import time

TOTAL_ATTRS = 2310

# Create attribute names "a0000" through "a2309"
attr_names = [f"a{i:04d}" for i in range(TOTAL_ATTRS)]

# Map each attribute to a default value (1..2310)
all_defaults = {name: i + 1 for i, name in enumerate(attr_names)}

# The provided factors of 2310
factors = [1, 2, 3, 5, 6, 7, 10, 11, 14, 15, 21, 22, 30, 33, 35, 42,
           55, 66, 70, 77, 105, 110, 154, 165, 210, 231, 330, 385,
           462, 770, 1155, 2310]

# Build a dictionary mapping each factor to a composite class.
# For factor f, create f subclasses each with (2310 // f) attributes,
# then create a composite class inheriting from all f subclasses.
composite_classes = {}
for f in factors:
    group_size = TOTAL_ATTRS // f
    subclasses = []
    for i in range(f):
        group = attr_names[i * group_size:(i + 1) * group_size]
        group_defaults = {name: all_defaults[name] for name in group}
        subclass = type(f"Sub_{f}_{i}", (object,), group_defaults)
        subclasses.append(subclass)
    composite_classes[f] = type(f"From_{f}", tuple(subclasses), {})

iterations = range(0, 1_000)

for n, c in composite_classes.items():
    i = c()
    t = time()
    for _ in iterations:
        for a in attr_names:
            getattr(i, a)
    print(f"Inheriting from {n} subclasses: {time()-t:.3f}s")

新的测试结果显示,性能衰减趋势看起来更接近线性,但数据中出现了一些奇怪的“平台台阶”:

![线性拟合下的数据点图]
![二次拟合下的数据点图]

备注:内容来源于stack exchange,提问作者Phrogz

火山引擎 最新活动