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

集合减法运算符与.difference()方法速度差异及实现区别解析

集合差集操作:-运算符与.difference()的实现差异及CPython/PyPy区别

测试背景

求两个集合的差集可通过-运算符或.difference()方法实现,以下是对比两者性能的测试代码:

import timeit

print(timeit.timeit('''
a.difference({b})
''', setup='''
a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
b = 3
'''))
# => 0.2423834060318768

print(timeit.timeit('''
a - {b}
''', setup='''
a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
b = 3
'''))
# => 0.2027170000365004

不同解释器下的测试结果

  • CPython运行输出:
0.24530324200168252
0.205820870003663

可见-运算符的执行速度比.difference()更快。

  • PyPy运行输出:
0.14613953093066812
0.23659668595064431

结果完全反转,.difference()的性能反超-运算符。

核心差异解析

-运算符与.difference()的实现区别

  1. 参数要求与处理

    • -运算符:要求右侧必须是集合类型,底层直接调用集合的__sub__特殊方法,跳过了类型检查和可迭代对象适配的步骤,仅针对集合执行差集计算。
    • .difference()方法:支持接收任意可迭代对象(如列表、元组),底层会先将传入的可迭代对象转换为临时集合,再执行差集逻辑。即便传入的是集合,方法本身仍会执行参数类型检查的流程,带来微小的额外开销。
  2. 调用路径开销

    • .difference()是普通方法调用,需要经过属性查找(定位a的difference属性)、方法绑定等步骤,这一系列操作会产生额外的执行成本。
    • -运算符是语言层面的语法糖,直接映射到__sub__方法,调用路径更短,在无JIT优化的解释器中优势明显。

CPython与PyPy的实现区别

  1. JIT编译优化差异

    • PyPy自带JIT即时编译,会对高频执行的代码路径进行深度优化。在本次测试场景中,PyPy能识别到.difference()的参数始终是集合,提前消除了不必要的类型转换与检查逻辑,甚至直接内联方法核心代码,使得方法调用的额外开销被完全抹平,最终性能反超运算符。
    • CPython是纯字节码解释执行,无JIT优化,运算符更短的调用路径(跳过属性查找与方法绑定)带来的性能优势更突出。
  2. 底层实现逻辑不同

    • CPython的集合基于C语言实现,__sub__与difference最终调用同一个底层C函数,但difference多了一层参数处理逻辑(检查可迭代对象、转换为集合),即使传入集合也无法完全跳过这层检查,产生微小开销。
    • PyPy的集合用RPython实现,其方法调用优化机制对.difference()更友好,结合JIT的动态优化,最终实现了比运算符更高效的执行效果。

内容的提问来源于stack exchange,提问作者Michael M.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 21:22:49