同一道题、同一份协议、同一把尺子。让四个模型用 Rust 从零实现一个内存 KV 存储服务, 再用统一压测套件量它们的性能工程能力。被测:Qwen3.8-Max、Claude Opus 4.8、Claude Fable 5、GPT-5.6 sol。
我们要一个不靠 LLM 当裁判的能力对照。性能是客观标量,天然抗刷分——只要压测器和用例不交给被测方,跑出来的吞吐/延迟就是硬数字。
KV 服务是理想标的:功能一句话说得清(GET/SET/DEL/EXPIRE),但"写好"的优化空间极深,从网卡字节到哈希表再回网卡的每一段都有讲究。而且它天然语言中立——一套压测客户端能打所有实现。
这套评测衡量的是"从零构建 + 性能优化"这一支能力,不是广义"代码质量"。
四家实现的正确性全部满分(27 条私有一致性用例全过,含协议边界、恶意帧、并发写、TTL 语义)。也就是说,"能不能写对"这件事四家没有区分度——全部的差距都在跑通之后的性能工程上。
所以本报告回答的是"各家性能强在哪、差在哪",而不是"谁综合最好"。后一个问题没有客观答案(见第 5 章)。
- 语言固定 Rust(edition 2021,工具链 1.83)。跨语言性能差数十倍,锁语言才可比。
- 协议固定:自造的 QKV 二进制协议(长度前缀 + opcode + LEB128 varint,四个命令)。自造是为了抗抄——没有现成实现可搬。
- 依赖白名单:仅 std + libc,禁 async runtime、禁第三方 KV/哈希/分配器 crate,核心逻辑必须自写。这样才测得出真实的并发模型与数据结构选择。
刻意精简,只给三样,不含任何优化提示:
PROMPT.md——任务书(写什么、交付什么、限制)PROTOCOL.md——协议规范(行为以它为准)smoke/——一组基础自测用例
题面明示协议语义(客户端会连续发多个请求、TCP 会任意分帧),但绝不提示"批量解析能提速"——这个优化断崖是主要区分点,说了就废了。
每个评测 job 拉起一对全新容器,跑完销毁:
┌ 服务端容器 (4 核 / 3G / 断网) ┐ ┌ 压测端容器 (8 核 / 6G) ┐
│ 断网编译并运行被测 qkvd │◄─────►│ 编译压测器,跑评测套件 │
│ 监听 :7777 │ 共享 └─────────────────────────┘
└────────────────────────────────┘ net+pid 命名空间
三个关键设计:
- 服务端断网编译——强制验证离线可编译,排除外网干扰
- 压测端独占 8 核、与服务端不重叠——防止压测端自己成为瓶颈
- 共享 pid 命名空间——压测端才能读到服务端进程的 RSS/CPU
规格由脚本常量固定,四家字面一致:服务端 4 核/3G/pids128/nofile65536,压测端 8 核/6G。全程串行,一次一个 job。
参考数据跑在 WSL2 上,--cpuset 经 Hyper-V 二次调度、超线程/turbo 不可控,故绝对值偏保守、相对结论可信。
一句话的 KV,优化空间藏在"字节到哈希表再回字节"的每一段。拆成 6 个点,按对性能的影响权重排序:
| 权重 | 技术点 | 可优化的是什么 |
|---|---|---|
| P0 写路径批处理 | 决定档位 | 一次 read 收到 N 条命令,是逐条 write 回,还是全部解析完、响应拼成一块一次 write。系统调用从 2N 降到 2。 |
| P1 并发与分片锁 | 高 | 事件循环怎么用满多核;共享哈希表分几片降低锁竞争;worker 数怎么定。 |
| P5 过载背压 | 中 | 请求涌入超过处理能力时,是无限吃进来撑爆缓冲,还是摘掉 EPOLLIN 主动限流。 |
| P4 内存布局与回收 | 中 | key/value 用 Box<[u8]>(精确) 还是 Vec<u8>(带冗余);value 能否 Arc 共享;缓冲用完是否收缩;过期怎么回收。 |
| P3 哈希算法 | 中低 | 默认 SipHash(抗DoS但慢) vs 自写 FxHash(KV 短 key 场景快 3-5 倍)。 |
| P2 零拷贝解析 | 低 | 解析时借用输入切片,还是每帧 to_vec() 拷一份。 |
权重是基于评测观察的判断估计,不是精确测量。P0/P1 合计约占区分度的七成。
两种压测范式,是六组最根本的分野:
| 组 | 范式 | 测什么 | 主测技术点 |
|---|---|---|---|
| G1 极限读 | 闭环满速 | 100% GET,并发×批次网格取峰值 | P0 |
| G2 极限写 | 闭环满速 | 100% SET | P0 + P1 |
| G3 读写 50/50 | 闭环满速 | 混合 | P0 + P1 |
| G4 长程稳定性 | 开环定速 | 固定 4 万 QPS × 120s | P4 + 单请求延迟 |
| G5 负载延迟曲线 | 开环定速 | 2/4/8/16 万 QPS 四档 p99 | P5(过载档) |
| G6 负载资源曲线 | 开环定速 | 同档位 RSS/CPU(与 G5 共用运行) | P4 内存斜率 |
核心指标:批处理增益 = 批次 256 吞吐 ÷ 批次 1 吞吐。它是全套里最可靠的——比值型,分子分母同机同码,机器快慢被约掉。跨轮吞吐波动 ±55% 时它仍稳定分档。
- key 空间 20 万(前缀+8位序号),value 固定 16B
- 访问分布:zipf 近似热点,90% 请求打在前 10% key 上
- 完全确定性:种子硬编码,四家跑逐字节相同的负载,不是随机
- 每个吞吐网格点重复 5 次取中位数(压制单次抖动)
- 压测端 CPU 同步采样,峰值超 8 核×85% 标"不可信"(防止测到客户端上限)
- 定速档 behind_schedule > 5% 标"该档无效"(防止定速没跟上)
- 可强断言(换机器也稳):数量级差距、批处理增益分档、吞吐排名≠延迟排名。
- 仅本配置成立:前三名精确次序(差 0.5-9% < 跨轮方差,统计不显著)、绝对 ops/s 值。对核数、批次上限敏感。
| Qwen3.8-Max | Opus 4.8 | Fable 5 | GPT-5.6 sol | |
|---|---|---|---|---|
| 极限读 G1 | 11.8M | 10.5M | 10.5M | 4.5M |
| 极限写 G2 | 12.2M | 9.6M | 8.7M | 4.7M |
| 读写 G3 | 10.2M | 8.8M | 9.1M | 4.7M |
| 批处理增益 | 99x | 92x | 98x | 12x→52x(v2) |
| Qwen3.8-Max | Opus 4.8 | Fable 5 | GPT-5.6 sol | |
|---|---|---|---|---|
| 长程 p99 (G4) | 217µs | 183µs | 191µs | 241µs |
| 8 万档 p99 (G5) | 390µs | 303µs | 369µs | 533µs |
| 过载档 p99 (G5) | 582µs | 909µs | 537µs | 716µs |
| RSS 随负载 (G6) | 30→34MB | 24.7MB | 27→28MB | 34MB |
| G1 | G2 | G3 | G4 | G5 | G6 | 夺冠 | |
|---|---|---|---|---|---|---|---|
| Qwen3.8-Max | 1 | 1 | 1 | 3 | 3 | 1 | 4 |
| Opus 4.8 | 2 | 2 | 3 | 1 | 1 | 3 | 2 |
| Fable 5 | 3 | 3 | 2 | 2 | 2 | 2 | 0 |
| GPT-5.6 sol | 4 | 4 | 4 | 4 | 4 | 4 | 0 |
- Qwen3.8-Max——吞吐三冠 + CPU 效率最高。客户端会批量发、在意机器成本时最优。
- Opus 4.8——延迟最优 + 内存最省。常规一问一答、在意延迟时最优。
- Fable 5——六项全第二、零短板、过载档尾延迟最稳。负载未知/怕过载雪崩时最优。
- GPT-5.6 sol——曾落后一个数量级,v2 修入 writev 后收窄到 2.5 倍,但仍全项第四。
不存在绝对最优,单一指标必然选错——这是本评测最重要的方法论产出。想比高下,得先锁定场景("读多写少+在意成本"→ 看吞吐 → Qwen 赢),把权重前提摆到台面上,而不是合成一个假装客观的总分。
四家架构高度同源(SO_REUSEPORT + 每 worker 独立 epoll + 分片 HashMap + 纯 std/libc),差距全在各技术点的具体取舍。以下为逐行源码归因。
| 实现 | 做法 | 结果 |
|---|---|---|
| Qwen/Opus/Fable | 一次 read 解析全部命令,响应拼一整块一次写 | 增益 92-99x,千万级 |
| GPT-5.6 sol 原版 | 每条命令单独一次 write(),libc 连 writev 都没声明 | 增益仅 12x,百万级(掉一个数量级) |
| sol v2 | 引入 writev 攒批,但不彻底 | 增益 52x,收窄到 2.5 倍 |
这是四家吞吐差 2.6-10 倍的头号原因。
- Qwen 1024 分片——写扩展最好,G2 领先 31%(分片价值只在写负载体现)。
- Fable/Opus 256 分片——够用,锁竞争近零。
- Opus 用 22 worker(=核数自适应)换低载延迟,但过载时调度抖动。
- sol 仅 64 分片 + 全局 AtomicUsize 记账——分片不足 + 原子争用,8 worker 反而最慢最费 CPU。
- Fable 5 是唯一真生效的背压——积压超 4MB 摘 EPOLLIN、降到 64KB 恢复,过载档 p99 最稳 537µs。
- Qwen 部分生效(582µs)。
- Opus 4.8 阈值设 16MB,对几字节的小响应形同虚设——低载延迟王,过载却塌到 909µs。
- sol 的全局 512MB 上限是争用源不是背压(1231µs,v2 后 716µs)。
- Opus 4.8——
Box<[u8]>精确 + 空分片零预分配 + 缓冲自收缩,RSS 最省 24.7MB。 - Fable 5——
Box<[u8]>+Arc<[u8]>共享 value + 增量轮扫过期,RSS 随负载几乎不涨(27→28MB)。 - Qwen——
Vec<u8>(带冗余) + HashMap 扩容不归还,RSS 随负载涨最多(30→34MB)。 - sol——
Vec+ 每请求约 4 次堆分配,写负载 RSS 曾达 47MB。
- Fable/Opus——自写 FxHash,CPU 低。
- Qwen——自己写了 fxhash64 却只用于选分片,内层 HashMap 仍用默认 SipHash(明显遗漏,拖累单请求延迟,这是它 G4 p99 偏高的直接原因)。
- sol——双重 SipHash(选分片+内层各一次),纯浪费 CPU。
- Qwen——零拷贝 body 借用 + 延迟 compact,每帧无额外分配。
- Fable——边界触发 copy_within,偶发 memmove。
- Opus——每帧全量 revalidate。
- sol——每帧 to_vec() 整帧复制,制造大量分配抖动。
Qwen 顶着两个短板(SipHash 未换、每轮扫全表)仍拿吞吐第一——因为它的优点全砸在最高权重的 P0/P1,缺点在中低权重的 P3/P5。而 Fable 5 是唯一每个技术点都不偷工的实现,所以六项全第二、零短板。这正是"综合工程最扎实"与"某场景性能最强"是两个不同问题的根源。
bash run-eval.sh # 四家 × 六组
bash run-eval.sh --rounds 3 # 三轮取中位数(更稳)题面、四家产物(含 vendor 离线可编译)、压测引擎、评分脚本全部在本目录。跨机器对比须同机重跑四家基线——绝对值不可跨环境比较。