50ms 模拟 DB 延迟下:PHP+Swoole 1912 RPS,Go 394 RPS,P99 却低一个数量级
信源:GitHub 仓库 phpbenchlab/cross-lang-io-benchmark 的 README,原始标题 PHP 8.5 vs Node.js vs Go vs Python: I/O Performance Benchmark (2026)。
- 仓库地址:https://github.com/phpbenchlab/cross-lang-io-benchmark
- 相关站点:https://phpbenchlab.com/
- License: MIT
测试环境(Test Environment)
- Server: 4 vCPU, 8 GB RAM, Ubuntu 22.04
- Database: MySQL 8.4
- PHP: 8.5.7 with JIT tracing, buffer 128M
- Swoole: 6.2.1, 20 workers, coroutine + PDO connection pool
- Node.js: 22.x, connection pool size 20
- Go: 1.24.x, database/sql connection pool size 20
- Python: 3.12.x, aiomysql connection pool size 20
关键结果(Key Results)
| Language | 50ms RPS | 50ms P99 | 200ms RPS | 200ms P99 |
|---|---|---|---|---|
| PHP+Swoole | 1,912 | 62 | 495 | 208 |
| Node.js | 393 | 256 | 99 | 1,008 |
| Go | 394 | 914 | 108 | 2,001 |
| Python | 393 | 461 | 99 | 2,600 |
| PHP-FPM | 388 | 264 | 99 | 1,016 |
关键观察:
- 模拟数据库延迟 50ms 时,PHP+Swoole 的 RPS 是 Go 的近 5 倍(1912 对 394),P99 不到后者的 1/10(62ms 对 914ms)。
- Node.js / Go / Python / PHP-FPM 的 RPS 几乎贴在同一水平(388–394),说明在固定连接池 + 模拟 DB 延迟下,吞吐被连接数而非语言运行时限制。
- 延迟拉到 200ms 后,各家 RPS 都掉到 99–108,PHP+Swoole 仍以 495 领先,但 P99 差距缩小:PHP+Swoole 208ms,Node 1008ms,Go 2001ms,Python 2600ms。
复现步骤(How to Replicate)
- Install PHP 8.5, Node.js 22, Go 1.24, Python 3.12, MySQL 8.4
- Clone this repository
git clone https://github.com/phpbenchlab/cross-lang-io-benchmark
- 运行
./run-all.sh启动所有服务 - 运行
./benchmark.sh执行基准测试 - 结果保存在
results/目录
仓库结构(Repository Structure)
仓库包含所有测试脚本、配置文件和原始结果。
需要注意的取舍与前提
- 这套基准来自一个以 PHP 为主题的基准站(phpbenchlab.com),PHP+Swoole 的配置写得最细(JIT tracing、128M buffer、20 workers、协程 + PDO 连接池),其他语言的连接池只设了 size 20。性能结论对配置极度敏感,不能当成语言本身的绝对排名。
- 4 vCPU / 8GB 的机器上,RPS 在 388–394 处"撞墙",是连接池 20 的上限特征,不是运行时上限。
- PHP+Swoole 用的是常驻内存 + 协程模型,和传统 PHP-FPM 的每请求重建进程完全不同——表里 PHP-FPM 只有 388 RPS 就是对照。把 Swoole 的成绩当作"PHP 快"是误读,它是"常驻协程运行时快"。
- 该仓库给了脚本和一键复现,建议在自己的硬件、自己的 SQL、自己的连接池参数下重跑一遍再用。