为什么Python中使用set字面量做成员包含检查远快于使用中间变量?
性能差异核心原因
你观察到的数倍性能差和垃圾回收无关,也不是针对集合包含检查的特殊运行时优化,本质是Python编译器的常量折叠优化导致两个测试用例的实际执行逻辑完全不同。
两个测试语句的实际执行差异
- 第一个测试语句
my_set = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} ; 10 in my_set
因为包含给变量my_set赋值的操作,属于带有副作用的语句,Python编译器不会随意消除这类操作,因此每轮执行都要完整完成「实例化集合对象→赋值给变量→执行成员检查」三个步骤,所有计算逻辑都是真实执行的,耗时自然高。 - 第二个测试语句
10 in {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
这是没有任何副作用的纯常量表达式,Python的字节码编译器会在编译阶段就完成所有计算:直接判断10是否属于给定的字面量集合,得到固定结果False后直接把整个表达式替换为常量值。也就是说你执行10^7次这个语句,本质上只是重复读取常量返回,完全没有创建集合、执行成员检查的操作,耗时当然会低很多。
验证方法
你可以用Python自带的字节码反汇编工具dis验证这个结论:
import dis # 对应第一个测试语句的逻辑 def test1(): my_set = {0,1,2,3,4,5,6,7,8,9} return 10 in my_set # 对应第二个测试语句的逻辑 def test2(): return 10 in {0,1,2,3,4,5,6,7,8,9} print("test1 字节码:") dis.dis(test1) print("\ntest2 字节码:") dis.dis(test2)
运行后可以看到test2的字节码里没有任何创建集合、成员判断的指令,只有直接加载常量返回的操作,而test1有完整的集合初始化、变量赋值、成员检查的逻辑。
内容的提问来源于stack exchange,提问作者sevan
相关产品推荐
相关产品推荐

