Benchmark 的問題在哪
每隔一段時間就會有 Reddit 或 Twitter 上有人貼一張圖,Actix-web / Axum / Hono 在最上面,Express 在快底部,然後說「Express 太慢了,快換 Actix」。
這個結論犯了一個常見的統計錯誤:用在「最有利條件下」量到的最大值,去預測在「你的實際條件下」的行為。
TechEmpower Benchmark 怎麼讀
TechEmpower Framework Benchmarks 是最被引用的框架效能測試,它有幾個 test type:
Plaintext:回傳一個純文字字串 Hello, World!,沒有 JSON 序列化,沒有資料庫。這個測試量的是框架本身的 HTTP 處理 overhead。
JSON:序列化一個 JSON object 回傳。量的是 JSON 序列化效能。
Single Query:查一次資料庫,回傳一筆 row。這才開始有 I/O。
Multiple Queries:對同一個請求查 20 次資料庫。I/O 密集場景。
Fortunes:查資料庫 + HTML template rendering。
你在網路上看到的「XX framework 最快」幾乎都是 Plaintext 或 JSON 的結果——這是框架差距最大的測試,因為沒有 I/O,framework overhead 佔的比例最高。
I/O-bound 才是你的真實情況
你的 API 幾乎必然是 I/O-bound:查資料庫要 5–50ms,打 Redis 要 0.5–2ms,呼叫外部 API 要 50–500ms。
在 I/O-bound 的情況下,框架本身的 CPU 處理時間(微秒等級)相比 I/O 等待(毫秒等級)是噪音。
一個查一次資料庫的 API:
總延遲 = 框架處理時間 + DB 查詢時間
≈ 0.1ms + 10ms
= 10.1ms
換最快的框架:
≈ 0.02ms + 10ms
= 10.02ms
差距:0.08ms → < 1%
TechEmpower 的 Single Query 測試結果,大多數框架在同等語言下差距在 2 倍以內,而不是 Plaintext 測試的 20 倍。
什麼情況框架效能才是瓶頸
CPU-bound workload:如果你的請求處理需要大量計算(圖片處理、PDF 生成、大批量資料轉換),框架層的效能差異才會有意義。但這種 workload 通常應該搬到 queue worker,不要阻塞 API server 的 event loop。
極高 QPS + 極低延遲要求:如果你的 API 需要每秒 100 萬請求、P99 延遲 < 1ms,你在做的是系統層級的工作,此時框架選型確實要很認真。但這個等級的需求在一般業務 API 裡是少數。
大量短暫連線:框架建立和銷毀 context 的效率在高頻短請求場景才明顯。
如何評估你的 API 效能
正確的做法是:profile 你自己的 API,找真正的瓶頸。
工具選擇:
wrk/k6:壓測工具,模擬真實的並發請求py-spy(Python)/clinic.js(Node.js):profile CPU 佔用- APM(Datadog / New Relic / OTel):找哪個 span 的時間最長
常見發現:
- 80% 的延遲在資料庫查詢(缺 index、N+1 query)
- 10% 在外部 API 呼叫(沒有 timeout、沒有 retry)
- 5% 在 JSON 序列化(超大 response body)
- < 1% 在框架本身
換框架解決的是那 < 1%;加 index 解決的是那 80%。
框架效能的真實 trade-off
| 框架 | Plaintext QPS(估計) | DB Query 下的相對差距 | 開發速度 |
|---|---|---|---|
| Axum / Actix(Rust) | 600 萬+ | 1.0x(基準) | 慢(Rust learning curve) |
| Fastify(Node.js) | 80 萬 | 1.1–1.3x | 快 |
| Hono(Node.js) | 70 萬 | 1.1–1.3x | 快 |
| Gin(Go) | 200 萬 | 1.1–1.5x | 快 |
| Express(Node.js) | 30 萬 | 1.2–1.8x | 最快 |
| FastAPI(Python) | 8 萬 | 1.5–3x | 快 |
| Spring Boot(Java) | 40 萬 | 1.1–1.5x | 中等 |
注意:DB Query 下的差距比 Plaintext 小得多,而且「開發速度」的損失通常遠大於「效能提升的收益」。
實際建議
不要因為 benchmark 選框架,除非你有確切的效能需求。
選框架的正確問題順序:
- 這個語言生態有哪些框架?
- 哪個和我的團隊技術棧最近?
- 哪個的生態、文件、社群對我的場景最友好?
- (最後才問)哪個效能最好?
如果你在問第 4 個問題之前沒有回答過「我現在的 API 瓶頸在哪裡」,那這個問題的答案對你的選型沒有意義。
