效能基準測試
如何對 Bun 進行基準測試
Bun 專為速度而設計。我們會對熱點路徑進行廣泛的效能分析和基準測試。Bun 所有公開基準測試的原始碼都位於 Bun 儲存庫的 /bench 目錄中。
測量時間
為了精確測量時間,Bun 提供了兩個執行環境 API:
- 符合 Web 標準的
performance.now()函式 Bun.nanoseconds(),它類似於performance.now(),但傳回的是應用程式啟動以來經過的時間,單位為納秒。使用performance.timeOrigin可將其轉換為 Unix 時間戳。
基準測試工具
- 對於微基準測試,我們推薦使用
mitata。 - 對於負載測試,你 必須使用 至少與
Bun.serve()一樣快的 HTTP 基準測試工具,否則測試結果會產生偏差。一些流行的基於 Node.js 的基準測試工具(例如autocannon)速度不夠快。我們推薦使用以下工具之一: - 對於基準測試指令碼或 CLI 命令,我們推薦使用
hyperfine。
測量記憶體使用
Bun 有兩個堆:一個用於 JavaScript 執行環境,另一個用於其他所有內容。
JavaScript 堆統計
bun:jsc 模組暴露了一些用於測量記憶體使用的函式:
import { heapStats } from "bun:jsc";
console.log(heapStats());
檢視範例統計
{
heapSize: 1657575,
heapCapacity: 2872775,
extraMemorySize: 598199,
objectCount: 13790,
protectedObjectCount: 62,
globalObjectCount: 1,
protectedGlobalObjectCount: 1,
// 堆中每種物件型別的計數
objectTypeCounts: {
CallbackObject: 25,
FunctionExecutable: 2078,
AsyncGeneratorFunction: 2,
'RegExp String Iterator': 1,
FunctionCodeBlock: 188,
ModuleProgramExecutable: 13,
String: 1,
UnlinkedModuleProgramCodeBlock: 13,
JSON: 1,
AsyncGenerator: 1,
Symbol: 1,
GetterSetter: 68,
ImportMeta: 10,
DOMAttributeGetterSetter: 1,
UnlinkedFunctionCodeBlock: 174,
RegExp: 52,
ModuleLoader: 1,
Intl: 1,
WeakMap: 4,
Generator: 2,
PropertyTable: 95,
'Array Iterator': 1,
JSLexicalEnvironment: 75,
UnlinkedFunctionExecutable: 2067,
WeakSet: 1,
console: 1,
Map: 23,
SparseArrayValueMap: 14,
StructureChain: 19,
Set: 18,
'String Iterator': 1,
FunctionRareData: 3,
JSGlobalLexicalEnvironment: 1,
Object: 481,
BigInt: 2,
StructureRareData: 55,
Array: 179,
AbortController: 2,
ModuleNamespaceObject: 11,
ShadowRealm: 1,
'Immutable Butterfly': 103,
Primordials: 1,
'Set Iterator': 1,
JSGlobalProxy: 1,
AsyncFromSyncIterator: 1,
ModuleRecord: 13,
FinalizationRegistry: 1,
AsyncIterator: 1,
InternalPromise: 22,
Iterator: 1,
CustomGetterSetter: 65,
Promise: 19,
WeakRef: 1,
InternalPromisePrototype: 1,
Function: 2381,
AsyncFunction: 2,
GlobalObject: 1,
AsyncFunction: 2,
GlobalObject: 1,
ArrayBuffer: 2,
Boolean: 1,
Math: 1,
CallbackConstructor: 1,
Error: 2,
JSModuleEnvironment: 13,
WebAssembly: 1,
HashMapBucket: 300,
Callee: 3,
symbol: 37,
string: 2484,
Performance: 1,
ModuleProgramCodeBlock: 12,
JSSourceCode: 13,
JSPropertyNameEnumerator: 3,
NativeExecutable: 290,
Number: 1,
Structure: 1550,
SymbolTable: 108,
GeneratorFunction: 2,
'Map Iterator': 1
},
protectedObjectTypeCounts: {
CallbackConstructor: 1,
BigInt: 1,
RegExp: 2,
GlobalObject: 1,
UnlinkedModuleProgramCodeBlock: 13,
HashMapBucket: 2,
Structure: 41,
JSPropertyNameEnumerator: 1
}
}
JavaScript 是一種垃圾回收語言,而非引用計數語言。物件在某些情況下不會立即釋放,這是正常且正確的;但物件永遠不被釋放則不正常。
要強制手動執行垃圾回收:
Bun.gc(true); // 同步執行
Bun.gc(false); // 非同步執行
堆快照可以顯示哪些物件沒有被釋放。使用 Bun.generateHeapSnapshot() 獲取堆快照,然後使用 Safari 或 WebKit GTK 開發者工具檢視。生成堆快照:
import { generateHeapSnapshot } from "bun";
const snapshot = generateHeapSnapshot();
await Bun.write("heap.json", JSON.stringify(snapshot, null, 2));
要檢視快照,請在 Safari 的開發者工具(或 WebKit GTK)中開啟 heap.json 檔案:
- 開啟開發者工具
- 點選「Timeline」(時間軸)
- 在左側選單點選「JavaScript Allocations」(JavaScript 分配)。可能需要點選鉛筆圖示才能顯示所有時間軸
- 點選「Import」(匯入),選擇你的堆快照 JSON

匯入後,你應該看到類似以下介面:

Web 偵錯程式的時間軸還會跟蹤正在執行的除錯會話的記憶體使用情況。
本地堆統計
Bun 使用 mimalloc 管理另一個堆。要列印非 JavaScript 記憶體使用情況的摘要,請呼叫 Bun.unsafe.mimallocDump()。
Bun.unsafe.mimallocDump();
heap stats: peak total freed current unit count
reserved: 64.0 MiB 64.0 MiB 0 64.0 MiB not all freed!
committed: 64.0 MiB 64.0 MiB 0 64.0 MiB not all freed!
reset: 0 0 0 0 ok
touched: 128.5 KiB 128.5 KiB 5.4 MiB -5.3 MiB ok
segments: 1 1 0 1 not all freed!
-abandoned: 0 0 0 0 ok
-cached: 0 0 0 0 ok
pages: 0 0 53 -53 ok
-abandoned: 0 0 0 0 ok
-extended: 0
-noretire: 0
mmaps: 0
commits: 0
threads: 0 0 0 0 ok
searches: 0.0 avg
numa nodes: 1
elapsed: 0.068 s
process: user: 0.061 s, system: 0.014 s, faults: 0, rss: 57.4 MiB, commit: 64.0 MiB
CPU 效能分析
使用 --cpu-prof 標誌分析 JavaScript 執行效能,以識別效能瓶頸。
bun --cpu-prof script.js
--cpu-prof 會寫入一個 .cpuprofile 檔案,你可以在 Chrome DevTools(效能面板 → 載入設定檔)或 VS Code 的 CPU 分析器中開啟該檔案。
Markdown 輸出
使用 --cpu-prof-md 來生成 Markdown 格式的 CPU 分析報告,這種格式便於 grep,且適合大型語言模型(LLM)分析:
bun --cpu-prof-md script.js
同時使用 --cpu-prof 和 --cpu-prof-md 可一次生成兩種格式:
bun --cpu-prof --cpu-prof-md script.js
你也可以通過 BUN_OPTIONS 環境變數傳遞該標誌:
BUN_OPTIONS="--cpu-prof-md" bun script.js
選項
bun --cpu-prof --cpu-prof-name my-profile.cpuprofile script.js
bun --cpu-prof --cpu-prof-dir ./profiles script.js
| 標誌 | 說明 |
|---|---|
--cpu-prof | 生成 .cpuprofile JSON 檔案(Chrome DevTools 格式) |
--cpu-prof-md | 生成 Markdown 格式的 CPU 分析報告 |
--cpu-prof-name <filename> | 設定輸出檔名 |
--cpu-prof-dir <dir> | 設定輸出目錄 |
堆分析
退出時寫入堆分析檔案,以分析記憶體使用情況並查詢記憶體洩漏。
bun --heap-prof script.js
--heap-prof 會在退出時寫入完整的 V8 格式堆快照,使用 Node.js 的診斷檔名格式(Heap.<yyyymmdd>.<hhmmss>.<pid>.<tid>.<seq>.heapprofile)。副檔名遵循 Node 的 --heap-prof 檔名約定。其內容與 v8.writeHeapSnapshot()/Bun.generateHeapSnapshot("v8") 相同。可通過 Chrome DevTools 的 Memory(記憶體)面板 → Load(載入)載入該檔案。選擇「All Files」(所有檔案),或將檔案重新命名為 .heapsnapshot。
Markdown 輸出
使用 --heap-prof-md 來生成適合 CLI 使用的 Markdown 堆分析報告:
bun --heap-prof-md script.js
選項
bun --heap-prof --heap-prof-name my-profile.heapprofile script.js
bun --heap-prof --heap-prof-dir ./profiles script.js
| 標誌 | 說明 |
|---|---|
--heap-prof | 在退出時寫入 .heapprofile 檔案 |
--heap-prof-md | 在退出時生成 Markdown 堆分析檔案 |
--heap-prof-name <filename> | 設定輸出檔名 |
--heap-prof-dir <dir> | 設定輸出目錄 |
--heap-prof-interval <bytes> | 為相容 Node.js 而接受(快照只會在退出時獲取一次;JavaScriptCore 沒有可應用間隔的分配取樣功能) |