curl 8.23.0 提速並瘦身:easy handle 縮小 28%
daniel.haxx.se(Daniel Stenberg)· 2026-10-13
curl 不再只靠「功能正確」過關:base64、URL 百分比編解碼、日期解析、printf 這些每個請求都會走過的小函式,在 8.23.0 被逐一換成更快的實作,核心結構體也一併縮小。這些改動預計隨 curl 8.23.0 在 2026-10-14 發布,作者 Daniel Stenberg 在發布前一天的部落格文章中列出了數字。
原本的問題
curl 是幾乎所有 Linux 發行版、嵌入式韌體與容器映像都會帶的 library 與工具,單次呼叫的開銷看似很小,但乘上每秒數千個連線或小型裝置的記憶體上限,就會變成真實成本。過去這類最佳化多半憑直覺,退步也不容易被發現。
2026-08-14 的前一篇文章說明了背景:curl 現在有一套含 24 項測試的效能套件,量測例如從 localhost 下載 100 GB 檔案的速度,以及單次 HTTP 下載需要多少次配置、多少位元組。該文也坦承,一次減少配置次數的合併「把其中一個主要結構體撐大了一點」,這正是需要測試去抓的取捨。
核心改動
文章列出的是一批熱路徑上的函式級加速,每一項都是把逐字元或逐位元組的處理改成更直接的做法,以下為原文給出的數字:
| 項目 | 8.23.0 的變化 |
|---|---|
| base64 編碼 | 快 2 倍以上 |
| base64 解碼 | 快 40% |
| URL 百分比解碼 | 快 2 倍以上 |
| URL 百分比編碼 | 約快 4 倍 |
| ASCII 日期轉 epoch 秒 | 快 2 倍以上 |
| 內部 ASCII 轉整數解析 | 幾乎快 2 倍 |
| URL 解析(數百個 URL 的測試) | 快 20% 到 30% |
printf() | 多數呼叫快 5% 到 15% |
日期解析的加速主要來自換掉星期、月份與時區的查找函式。printf() 的加速則因為 libcurl 自己的實作現在一次處理一段資料,不再逐位元組處理。URL 解析除了變快,也能更精確地回報無效 URL。
結構體瘦身
另一半改動針對記憶體。文章給的 before / after 如下:
| 結構體 | 舊(位元組) | 新(位元組) |
|---|---|---|
| easy handle | 4256 | 3064 |
| multi handle | 900 | 656 |
connectdata | 824 | 656 |
文章稱 easy handle 縮小約 28%、multi handle 約 27%、connectdata 略高於 20%,這些百分比是在讀者 Jeremy Robst 指出算錯後更正過的版本。easy handle 是每個傳輸一個,multi handle 與 connectdata 則和連線數相關,所以同時開很多傳輸的程式,節省會依連線數線性放大。
實測方面,用 curl 工具下載 512MB 的 HTTP 檔案,配置次數從 100 降到 96,峰值記憶體從 130,622 降到 126,875 位元組。這個峰值包含 102,400 位元組的下載緩衝區;文章說扣掉緩衝區後記憶體少 15%,但依文中兩個數字扣除緩衝區(28,222 到 24,475)計算約為 13%,原文基準可能不同,文章未說明。
影響範圍
一般使用者升級後不必改任何東西,行為與 API 不變。但有幾類人會直接受益或需要注意。
- 高併發的 libcurl 使用者(代理、爬蟲、推送服務):每個 easy handle 少約 1.2 KB,handle 池越大越明顯。
- 記憶體吃緊的嵌入式與 NAS 類裝置:結構體縮小與配置次數減少直接降低常駐用量。
- 大量處理 URL 的程式:URL 解析、百分比編解碼與日期解析都在請求路徑上,收益會累積。
- 依賴 URL 錯誤訊息文字的測試:既然無效 URL 的回報更精確,比對舊錯誤字串的腳本值得跑一次。
文章未提供個別 commit 或 PR 連結,也沒有說明各項加速的具體演算法;效能測試位於 curl 的 git 儲存庫,但文中未附連結。想驗證自己環境的效果,應以 8.23.0 與前一版在相同工作負載下實測。