Python Enum相等性校验性能为何比字符串慢2.5倍?
为什么Python中Enum的相等性校验比字符串慢约2.5倍?
Enum是星期、月份等可枚举类型的良好抽象,但测试显示这类类型的相等性校验性能比字符串慢约2.5倍。以下为测试代码及结果,分析性能差异的原因:
测试代码
import enum import timeit class IntDow(enum.Enum): MONDAY=enum.auto() TUESDAY=enum.auto() WEDNESDAY=enum.auto() THURSDAY=enum.auto() FRIDAY=enum.auto() SATURDAY=enum.auto() SUNDAY=enum.auto() class StrDow(str, enum.Enum): MONDAY="MONDAY" TUESDAY="TUESDAY" WEDNESDAY="WEDNESDAY" THURSDAY="THURSDAY" FRIDAY="FRIDAY" SATURDAY="SATURDAY" SUNDAY="SUNDAY" int_mon = IntDow["MONDAY"] int_tue = IntDow["TUESDAY"] str_mon = StrDow["MONDAY"] str_tue = StrDow["TUESDAY"] raw_mon = "MONDAY" raw_tue = "TUESDAY"
测试结果
>>> timeit.timeit(lambda: int_mon == IntDow.MONDAY, number=100000) 0.017555099999299273 >>> timeit.timeit(lambda: int_mon == int_tue, number=100000) 0.00824300000022049 >>> timeit.timeit(lambda: int_mon == IntDow.TUESDAY, number=100000) 0.018771999999444233 >>> timeit.timeit(lambda: str_mon == StrDow.MONDAY, number=100000) 0.01836639999964973 >>> timeit.timeit(lambda: str_mon == StrDow.TUESDAY, number=100000) 0.01744440000038594 >>> timeit.timeit(lambda: str_mon == str_tue, number=100000) 0.007430400000885129 >>> timeit.timeit(lambda: raw_mon == "MONDAY", number=100000) 0.007222599999295198 >>> timeit.timeit(lambda: raw_mon == "TUESDAY", number=100000) 0.00726819999908912 >>> timeit.timeit(lambda: raw_mon == raw_tue, number=100000) 0.007780600000842242
性能差异的原因
- Enum的相等性校验逻辑更复杂:Python的
Enum类重载了__eq__方法,比较两个Enum实例时,首先会检查对方是否属于同一Enum类,确认类型匹配后才会比较成员的value值。而字符串的相等性校验是底层C实现的直接内存或内容比较,逻辑简单高效。 - 类属性访问的额外开销:当使用
IntDow.MONDAY这种形式访问枚举成员时,每次都要通过类的属性查找机制获取实例,这比直接引用已赋值的字符串变量多了一层属性查找的耗时。从测试结果也能验证这一点:直接比较两个已赋值的Enum实例(如int_mon == int_tue)耗时和字符串接近,但比较实例与类成员(如int_mon == IntDow.MONDAY)时耗时明显上升。 - 混合枚举的兼容处理:对于
StrDow这种同时继承自str和Enum的混合枚举,其__eq__方法还要处理与普通字符串的兼容比较(比如支持StrDow.MONDAY == "MONDAY"),额外的逻辑分支会进一步增加校验的开销。 - 底层实现层面的差异:字符串是Python的内置基础类型,其核心操作(包括相等性校验)都在C层面实现,执行速度极快;而
Enum是用Python代码实现的类(即使有部分优化),其方法调用和逻辑判断都在Python解释器层面执行,天然比内置类型的操作更慢。
内容的提问来源于stack exchange,提问作者Genuine
相关产品推荐
相关产品推荐

