Skip to content

Bun は速度のために設計されています。ホットパスは広範にプロファイリングおよびベンチマークされています。Bun のすべての公開ベンチマークのソースコードは、Bun リポジトリの /bench ディレクトリで見つけることができます。

時間の測定

正確に時間を測定するために、Bun は 2 つのランタイム API 関数を提供します:

  1. Web 標準の performance.now() 関数
  2. Bun.nanoseconds() - これは performance.now() と似ていますが、アプリケーション開始からの現在時刻をナノ秒で返します。performance.timeOrigin を使用して、これを Unix タイムスタンプに変換できます。

ベンチマークツール

独自のベンチマークを作成する際は、適切なツールを選択することが重要です。

  • マイクロベンチマークには、汎用ツールとして mitata が最適です。
  • 負荷テストには、Bun.serve() と同等以上の速度を持つ HTTP ベンチマークツールを使用しなければなりません。そうでないと結果が歪められます。autocannon のような一部の Node.js ベースのベンチマークツールは十分に高速ではありません。以下のいずれかを推奨します:
  • スクリプトや CLI コマンドのベンチマークには、hyperfine を推奨します。

メモリ使用量の測定

Bun には 2 つのヒープがあります。1 つは JavaScript ランタイム用、もう 1 つはその他すべて用です。

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 by www.bunjs.com.cn 編集