Python几种并发实现方案的性能比较(Elias)
早期(约2007-2008,Python 2.4 时代)的一篇经典中文实测文章,作者 Elias。针对 Stackless Python、thread 模块、threading+Queue 模块、processing(多进程)+Queue 模块四种并发方案,用与《Erlang vs. Stackless Python: a first benchmark》相同的环形消息实验做性能对比。原文为博客打印 PDF(7页),数值结果表格以图片嵌入无法提取(标注:待确认具体耗时数字),文字结论完整。
实验设计
- 环形传递问题:n 个节点组成环,m 个消息逐个从 1 号节点发出,1..n-1 号收到后转发下一号,n 号收到即终止;以完成全部处理的总时间评判性能
- 参数:n=300、m=10000(可扩至 m=90000);全部用 no_io 版本(print 开销大,会污染测试)
- 平台:Macbook Pro 3,1 + Vmware Fusion 1.0 虚拟机(Debian etch),单核、796MB 内存;Python 2.4.4 + Stackless 3.1b3 + processing-0.52
核心结论(文字部分完整可读)
- Stackless Python 性能”匪夷所思”地好:比其他三种方案快几十倍;借助其 channel 机制实现也最简单。文章推测这解释了沈仙人基于 Stackless Python 的 Eurasia3 为何能达到 C 语言效果的并发性能
- thread 与 threading 性能差不多(threading 只是 thread 的封装),但 threading+Queue 测试结果不稳定(同代码多轮波动大,原因文中未解);工程体验上 threading+Queue 比裸 thread 轻松且少出错
- processing 多进程比 thread 慢约一倍,且这是特意给虚拟机调大内存避免 swap 后的结果(其他方案仅占少量内存);多开 CPU 核心时 processing 可能占优
- 多核利用限制:thread 模块不能有效利用多 CPU(GIL);实测 Stackless Python 开双核与单核性能相同,同样不能利用多核
- 给出的工程建议(当时Python社区共识):按 CPU 数启动少量进程,进程内部再开线程做业务,processing + 其自带 Queue 编程体验不错。这正是后来 multiprocessing 的标准用法雏形
历史价值与今天的映射
- 2007 年的结论框架至今仍然成立:GIL 限制线程多核扩展、多进程绕开 GIL 但切换贵、微线程(现在叫协程 asyncio/greenlet)在单线程事件循环下切换成本极低
- Stackless Python 的”快几十倍”本质是 callable-architectures 微线程 + channel,类比今天的 asyncio/greenlet vs OS 线程
- Eurasia3 是 Web.py 生态沈崴的作品(Stackless 系 Web 框架),此文是其性能背书的一手材料
- 具体毫秒级数字在原文中以图片呈现,本地提取不可得,待确认(如需可 OCR 第 4-5 页)
关联
- 云盘同目录还有 hate_django、Python入门 等资料
- 与 软件形式化方法-课程讲义全套-王捍贫 中并发程序交错语义互补:该文建模视角解释了为什么线程交错测试有 state-space explosion