Python 3.13自由线程解释器性能不及GIL版本,是否理解有误?
自由线程解释器(Python 3.13t)性能反而更差的原因
测试环境与结果
- 使用版本:
python-3.13.0rc2-amd64(含自由线程版本python3.13t) - 测试代码:
from concurrent.futures import ThreadPoolExecutor from random import randint import time def create_table(size): a, b = size table = [] for i in range(0, a): row = [] for j in range(0, b): row.append(randint(0, 100)) table.append(row) return table if __name__ == "__main__": start = time.perf_counter() with ThreadPoolExecutor(4) as pool: result = pool.map(create_table, [(1000, 10000) for _ in range(10)]) end = time.perf_counter() print(end - start, *[len(each) for each in result])
- 实测耗时:
- python3.13t(自由线程):56秒
- python3.13(启用GIL):26秒
- python3.12:25秒
- 基准测试对比:

核心问题:你的测试场景完全不匹配自由线程的设计目标
自由线程解释器(FTP)的初衷是让CPU密集型的Python代码能真正利用多核心并行,但它目前的实现特性恰好让你的测试场景效率暴跌:
细粒度锁的额外开销
原来的GIL是一把全局大锁,虽然限制了并行,但锁操作的开销极低。而FTP用细粒度锁替代GIL——每个Python对象、每个字节码操作都要加锁解锁,你的测试全是Python层面的循环、列表操作,每一步都要处理这些锁,自然比GIL版本慢一倍多。randint的线程安全额外成本
在GIL版本中,同一时间只有一个线程执行Python代码,randint不需要额外同步就能保证安全。但FTP下randint必须做线程安全处理,内部加锁逻辑会带来大量额外开销,而你的测试恰恰频繁调用这个函数,开销被进一步放大。任务数与线程数的不合理配置
你用4线程池跑10个任务,在FTP下多线程并行执行时,CPU核心竞争、锁争抢会导致大量上下文切换,反而拖慢整体速度。如果你的CPU是4核,任务数应该和核心数匹配,才能避免不必要的竞争。
自由线程的正确打开方式
FTP真正能发挥优势的场景:
- 任务是纯CPU密集型的Python字节码执行,且任务之间几乎没有共享状态(减少锁竞争)
- 任务数量与CPU核心数一致,避免过度竞争
- 避免大量调用需要额外同步的内置函数(比如
random模块的方法)
验证建议
你可以换个纯计算的测试场景试试,比如:
from concurrent.futures import ThreadPoolExecutor import time def compute_heavy(x): # 无共享状态的纯计算任务 result = 0 for i in range(10**8): result += i * x return result if __name__ == "__main__": start = time.perf_counter() # 任务数等于CPU核心数(比如4核就设4个任务) with ThreadPoolExecutor(4) as pool: result = pool.map(compute_heavy, [1,2,3,4]) end = time.perf_counter() print(end - start, list(result))
这种场景下,FTP版本的性能应该会超过GIL版本。
内容的提问来源于stack exchange,提问作者Boyang Li
相关产品推荐
相关产品推荐

