为何sum函数使用自定义类实例作为start参数时速度更慢?
为什么Python sum函数使用自定义类实例作为start参数时性能更慢?
测试案例与结果
案例1:自定义类实例作为start参数
source = """ class A: def __init__(self, a): self.a = a def __add__(self, other): return self.a + other; sum([*range(10000)], start=A(10)) """ import timeit print(timeit.timeit(stmt=source))
测试耗时:约192.607秒
案例2:int类型作为start参数
source = """ class A: def __init__(self, a): self.a = a def __add__(self, other): return self.a + other; sum([*range(10000)], start=10) """ import timeit print(timeit.timeit(stmt=source))
测试耗时:约111.483秒
系统信息:
>>> import platform >>> platform.platform() 'macOS-12.5-arm64-arm-64bit' >>> import sys >>> sys.version '3.11.0 (v3.11.0:deaf509e8f, Oct 24 2022, 14:43:23) [Clang 13.0.0 (clang-1300.0.29.30)]'
性能差异的核心原因
内置类型的底层优化
CPython的sum函数对int等内置数值类型做了深度优化,核心累加逻辑用C语言实现,直接执行高效的底层整数加法,完全跳过Python层面的函数调用开销。自定义类的方法调用开销
当start是自定义类A的实例时,每一次累加都需要触发Python层面的__add__方法调用:包括属性查找(self.a)、栈帧创建、参数传递、返回值处理等操作,这些步骤的耗时远高于C级别的内置操作。优化路径的触发条件
sum函数会根据start的类型选择执行路径:只有当start是内置数值类型时,才会启用专门的快速累加分支;如果是自定义对象,只能走通用的对象加法逻辑,无法利用任何针对内置类型的优化。
即使你的__add__最终返回int,但因为初始start是自定义实例,sum全程都无法切换到快速路径,只能持续执行Python层面的加法逻辑,这就是性能差距的根源。
内容的提问来源于stack exchange,提问作者user459872
相关产品推荐
相关产品推荐

