Skip to content

Bun 專為速度而設計。關鍵路徑已經過廣泛的性能分析和基准測試。所有 Bun 公開基准測試的源代碼可以在 Bun 倉庫的 /bench 目錄中找到。

測量時間

為了精確測量時間,Bun 提供了兩個運行時 API 函數:

  1. Web 標准的 performance.now() 函數
  2. Bun.nanoseconds() 類似於 performance.now(),但它返回應用程序啟動後經過的納秒數。你可以使用 performance.timeOrigin 將其轉換為 Unix 時間戳。

基准測試工具

在編寫自己的基准測試時,選擇合適的工具很重要。

  • 對於微基准測試,一個很好的通用工具是 mitata
  • 對於負載測試,你 必須使用 至少與 Bun.serve() 一樣快的 HTTP 基准測試工具,否則結果會有偏差。一些流行的基於 Node.js 的基准測試工具(如 autocannon)不夠快。我們推薦使用以下工具之一:
  • 對於基准測試腳本或 CLI 命令,我們推薦使用 hyperfine

測量內存使用量

Bun 有兩個堆。一個堆用於 JavaScript 運行時,另一個堆用於其他所有內容。

JavaScript 堆統計

bun:jsc 模塊提供了一些用於測量內存使用的函數:

ts
import { heapStats } from "bun:jsc";
console.log(heapStats());

查看示例統計

ts
{
  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,
    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 是一種垃圾回收語言,而不是引用計數語言。在某些情況下,對象不會立即釋放是正常且正確的,盡管對象永遠不被釋放是不正常的。

要手動強制運行垃圾回收:

ts
Bun.gc(true); // 同步
Bun.gc(false); // 異步

堆快照讓你檢查哪些對象沒有被釋放。你可以使用 bun:jsc 模塊獲取堆快照,然後使用 Safari 或 WebKit GTK 開發者工具查看它。要生成堆快照:

ts
import { generateHeapSnapshot } from "bun";

const snapshot = generateHeapSnapshot();
await Bun.write("heap.json", JSON.stringify(snapshot, null, 2));

要查看快照,在 Safari 的開發者工具(或 WebKit GTK)中打開 heap.json 文件:

  1. 打開開發者工具
  2. 點擊 "Timeline"
  3. 點擊左側菜單中的 "JavaScript Allocations"。它可能不可見,直到你點擊鉛筆圖標顯示所有時間線
  4. 點擊 "Import" 並選擇你的堆快照 JSON

導入後,你應該看到類似這樣的內容:

Web 調試器 也提供時間線功能,允許你跟蹤和檢查運行中調試會話的內存使用情況。

原生堆統計

Bun 使用 mimalloc 作為另一個堆。要報告非 JavaScript 內存使用的摘要,設置 MIMALLOC_SHOW_STATS=1 環境變量,統計信息將在退出時打印。

sh
MIMALLOC_SHOW_STATS=1 bun script.js
txt
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 執行以識別性能瓶頸。

sh
bun --cpu-prof script.js

這會生成一個 .cpuprofile 文件,你可以在 Chrome DevTools(Performance 標簽頁 → Load profile)或 VS Code 的 CPU 分析器中打開它。

選項

sh
bun --cpu-prof --cpu-prof-name my-profile.cpuprofile script.js
bun --cpu-prof --cpu-prof-dir ./profiles script.js
標志描述
--cpu-prof啟用分析
--cpu-prof-name <filename>設置輸出文件名
--cpu-prof-dir <dir>設置輸出目錄

Bun學習網由www.bunjs.com.cn整理維護