基准实测
数字来自 go test -bench 实跑,最新一轮是 2026-10-01 轻载窗口(9 靶 × 10 轮,benchstat 聚合),复现命令见文末;README 的性能表与本页主表同源同一次实跑。看表之前先说口径:跨机器、跨窗口只比相对关系,绝对值是 CPU 供给与负载的函数——ns/op 只当量级看,allocs/op 与 B/op 才是确定性结论。历史上另测过两个窗口(2026-09-28 高负载、2026-09-30 同负载读数复测),完整读数保留在「历史窗口对照」一节。
环境与参数(2026-10-01 轻载窗口)
- CPU:Intel Core i9-10880H @ 2.30GHz(14 逻辑核在线),内存 51GiB,linux/amd64,Go 1.27.1
- 机器负载:开跑前 1min loadavg 3.00、跑完 9.45(5min 3.26 → 16.72,15min 12.40 → 15.81)——窗口内负载爬升,但对 14 逻辑核仍属轻到中载,远低于 2026-09-28 窗口的 90–105(超载约 7 倍)
- 并发口径:全部基准单 goroutine 顺序执行;端到端是单连接上的同步 Request/Response 往返,测的是库整体往返延迟,不是吞吐上限(
bench_test.go原注释即此意) - 端到端载荷:请求 payload 为
nil、响应为{"n":1}(约 7B)——这组两行几乎不含载荷编解码成本,测的是系统调用与调度 - 参数:
-benchmem -count=10 -benchtime=1s,9 个基准 × 10 轮 = 90 个样本,benchstat聚合;表中 ± 为样本间变异系数 - allocs/op 九靶全部 ±0%;B/op 除 flate 相关两行(压缩器内部缓冲路径,实测 5 023–5 677 / 5 313–5 815,相对均值 ±8% 以内)外同样稳定
数据(2026-10-01 轻载窗口)
帧解码(ReadFrame;编码在计时器外预置,环内只解码)
| 载荷 | 每帧耗时 | 解码线速 | B/op | allocs/op |
|---|---|---|---|---|
| 64 B | 594.6 ns ± 19% | 183 MB/s | 216 | 6 |
| 1 KiB | 1.77 µs ± 12% | 607 MB/s | 1.15 Ki | 6 |
| 64 KiB | 33.4 µs ± 8% | 1 976 MB/s | 64.15 Ki | 6 |
变换管线(outbound + inbound 往返,~1.3 KiB 重复 JSON)
| 组合 | 耗时 | B/op | allocs/op |
|---|---|---|---|
| 明文直通 | 14.4 ns ± 5% | 0 | 0 |
| 仅压缩(flate) | 27.3 µs ± 7% | ~5.31 Ki | 8 |
| 仅加密(AES-256-GCM) | 7.67 µs ± 6% | 3.02 Ki | 3 |
| 压缩+加密 | 29.0 µs ± 8% | ~5.45 Ki | 11 |
端到端(完整链路:编码 → TCP 回环 → 解码 → 分发 → handler → 响应回程)
| 组合 | 单次往返 | 折算单连接顺序吞吐 | allocs/op |
|---|---|---|---|
| 明文 | 121.9 µs ± 9% | ~8,200 req/s | 33 |
| 加密 | 128.1 µs ± 6% | ~7,800 req/s | 39 |
折算 req/s = 1 ÷ 单次往返,是单连接顺序请求的口径;多路复用下并发流的总吞吐远高于此。请求载荷为 nil、响应约 7B,所以这两行的墙时由系统调用与调度主导,几乎不含载荷编解码成本。
逐项解读:开销主要在哪
- 端到端的大头不在编解码,在系统调用与调度。1 KiB 帧解码 1.77 µs、变换直通 14 ns,而一次完整往返 121.9 µs——差距是 TCP 回环收发的系统调用、goroutine 唤醒与读写调度;按端到端自身的 7B 载荷折算,编解码与变换合计不足单次往返的 3%。协议层本身很薄,优化应优先看 I/O 与并发模型,不是帧格式。
- 压缩比加密贵约 3.6 倍。同一 1.3 KiB 载荷:flate 27.3 µs vs AES-256-GCM 7.67 µs。延迟敏感、带宽不敏感的场景应只开加密;两者是参数化开关、握手协商生效(双方都开才启用),可以按场景只选其一。该比值跨窗口浮动很大(见「历史窗口对照」与 DESIGN §11.2):本窗口 3.6×、2026-09-30 复测 3.7×、DESIGN §11.2 低负载表 5.5×、2026-09-28 高负载窗口 4.8×、更早的 README 空载表曾达 12×——flate 对 CPU 争用远比走 AES-NI 硬件加速的 GCM 敏感。
- 压缩+加密不是相加关系。29.0 µs < 27.3 + 7.67:两次缓冲分配等固定成本被共享;且管线先压后加,加密的输入已经变小。
- 帧层是 O(载荷) 的拷贝主导,固定 6 次分配。allocs/op 与载荷大小无关(头部、metadata、缓冲等固定结构),B/op 随载荷线性。64 KiB 档 1 976 MB/s 解码线速对应单核约 30 000 帧/s;多路复用下吞吐按流并行。
- 开关关闭零成本。明文直通 0 allocs、14.4 ns:变换管线未启用时是纯直通,不为「可压缩可加密」的设计付任何接口与包装代价。
- 加密的端到端增量与单元基准自洽。往返 +6.2 µs(+5%);该差值与两组各自的样本标准误同量级,只当量级看。确定的部分是分配 33 → 39 恰好 +6,即两个方向各一次 outbound+inbound,与
TransformEncrypt的 3 allocs/op 逐一对上——开销可解释、无隐藏放大。
与覆盖率门禁的口径关系
基准不进覆盖率:CI 的覆盖率门禁步骤(go test -coverprofile)不带 -bench,基准代码在 _test.go 里也不参与库包语句覆盖统计,codecov 上传的 profile 不含基准执行路径——本页与既有口径互不影响(库包语句覆盖 100% 门禁、Codecov 行覆盖 project target 99%(range 95..100,badge 四舍五入显示 100%)+ patch 100%,逐项含义见 FAQ)。
历史窗口对照
同一套 9 靶在另外两个窗口的读数,保留作对照。三轮的 allocs/op 完全一致(跨窗口复现的核心结论),B/op 除「仅压缩」一行有约 8% 差异(4.92 Ki → ~5.31 Ki,压缩器内部缓冲路径)外也一致,差的全是墙时。
2026-09-28 高负载窗口
测量时机器处于高负载(同机其他并行工程的编译与构建任务,超载约 7 倍,1min loadavg ≈ 90–105,窗口前后实测 102.58 → 89.16;Go 1.27.1,同为 -count=10 -benchtime=1s),墙时普遍偏慢且方差大:
| 指标 | 09-28 高负载 | 10-01 轻载 | 高/轻 |
|---|---|---|---|
| 帧解码 64 B | 3.96 µs ± 82%(25.0 MB/s) | 594.6 ns ± 19%(183 MB/s) | 6.7× |
| 帧解码 1 KiB | 7.59 µs ± 158%(133.8 MB/s) | 1.77 µs ± 12%(607 MB/s) | 4.3× |
| 帧解码 64 KiB | 163.2 µs ± 58%(391.3 MB/s) | 33.4 µs ± 8%(1 976 MB/s) | 4.9× |
| 变换·明文直通 | 122 ns ± 74% | 14.4 ns ± 5% | 8.5× |
| 变换·仅压缩 | 130.4 µs ± 65%(4.92 Ki) | 27.3 µs ± 7%(~5.31 Ki) | 4.8× |
| 变换·仅加密 | 27.2 µs ± 27%(3.02 Ki) | 7.67 µs ± 6%(3.02 Ki) | 3.5× |
| 变换·压缩+加密 | 138.4 µs ± 39%(5.48 Ki) | 29.0 µs ± 8%(~5.45 Ki) | 4.8× |
| 端到端·明文 | 437.1 µs ± 44%(~2,300 req/s) | 121.9 µs ± 9%(~8,200 req/s) | 3.6× |
| 端到端·加密 | 570.1 µs ± 40%(~1,750 req/s) | 128.1 µs ± 6%(~7,800 req/s) | 4.5× |
| allocs/op(九靶) | 与轻载窗口完全一致 | — | 1.0× |
同靶相差 3.5~8.5×,1 KiB 档 ±158% 的离群方差即来自调度风暴——分配列不受影响。
2026-09-30 复测注
相近 loadavg(1min ≈ 88–103)下 -count=3 -benchtime=2s 复跑,帧 64B/1KiB/64KiB ≈ 0.85µs / ~2.1µs / ~40µs(~1.6 GB/s),flate/GCM 往返 ≈ 28.5µs / 7.8µs,RTT 明文 ≈ 126µs(加密 +12µs);allocs/op 与 B/op 两列完全复现。该轮与本页 2026-10-01 轻载窗口在全部时间列上相差 ≤1.5×——两轮独立的非超载窗口互相印证,超载窗口则慢 3.5~8.5×。可见 loadavg 读数相近不代表 CPU 争用强度相近(测量当日是编译风暴,复测日负载构成不同),高负载窗口的绝对值只在测量当口成立,同样的负载读数下复跑快 3.5~4.7×。
复现命令
# 全量:9 靶 × 10 轮,约 2–3 分钟(本文口径)
go test -run '^$' -bench . -benchmem -count=10 -benchtime=1s . | tee bench.txt
# 统计聚合(均值 ± 变异系数)
go install golang.org/x/perf/cmd/benchstat@latest
benchstat bench.txt
# 只跑某一组
go test -run '^$' -bench 'FrameRoundTrip' -benchmem -count=10 .
go test -run '^$' -bench 'RequestResponse' -benchmem -count=10 .
# CI 冒烟口径(每靶 1 次迭代,只验证不挂,数字无意义)
go test -bench . -benchtime 1x ./...解读数字记住两条:跨机器只比相对关系不比绝对值(吞吐是 CPU 供给与负载的函数);-benchtime 1x 的冒烟输出不是性能数据。