Skip to content

Bun ist auf Geschwindigkeit ausgelegt. Hot Paths werden umfassend profiliert und benchmarkt. Der Quellcode für alle öffentlichen Benchmarks von Bun befindet sich im /bench Verzeichnis des Bun Repositories.

Zeit messen

Um Zeit präzise zu messen, bietet Bun zwei Runtime-API-Funktionen:

  1. Die Web-Standard performance.now() Funktion
  2. Bun.nanoseconds() ähnlich wie performance.now(), gibt jedoch die aktuelle Zeit seit dem Start der Anwendung in Nanosekunden zurück. Sie können performance.timeOrigin verwenden, um dies in einen Unix-Zeitstempel umzuwandeln.

Benchmarking-Tools

Beim Schreiben eigener Benchmarks ist es wichtig, das richtige Tool zu wählen.

  • Für Mikrobenchmarks ist mitata ein hervorragendes Allzweck-Tool.
  • Für Lasttests müssen Sie ein HTTP-Benchmarking-Tool verwenden, das mindestens so schnell ist wie Bun.serve(), da sonst Ihre Ergebnisse verzerrt werden. Einige beliebte Node.js-basierte Benchmarking-Tools wie autocannon sind nicht schnell genug. Wir empfehlen eines der folgenden:
  • Für Benchmarking-Skripte oder CLI-Befehle empfehlen wir hyperfine.

Speichernutzung messen

Bun hat zwei Heaps. Ein Heap ist für die JavaScript-Runtime und der andere Heap für alles andere.

JavaScript Heap-Statistiken

Das bun:jsc Modul exposes einige Funktionen zum Messen der Speichernutzung:

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

Beispielstatistiken anzeigen

ts
{
  heapSize: 1657575,
  heapCapacity: 2872775,
  extraMemorySize: 598199,
  objectCount: 13790,
  protectedObjectCount: 62,
  globalObjectCount: 1,
  protectedGlobalObjectCount: 1,
  // Eine Zählung jedes Objekttyps im Heap
  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 ist eine garbage-collectete Sprache, nicht referenzzählend. Es ist normal und korrekt, dass Objekte nicht in allen Fällen sofort freigegeben werden, obwohl es nicht normal ist, dass Objekte niemals freigegeben werden.

Um die Garbage Collection manuell zu erzwingen:

ts
Bun.gc(true); // synchron
Bun.gc(false); // asynchron

Heap-Snapshots ermöglichen es Ihnen zu inspizieren, welche Objekte nicht freigegeben werden. Sie können das bun:jsc Modul verwenden, um einen Heap-Snapshot zu erstellen und ihn dann mit Safari oder WebKit GTK Developer Tools anzuzeigen. So generieren Sie einen Heap-Snapshot:

ts
import { generateHeapSnapshot } from "bun";

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

Um den Snapshot anzuzeigen, öffnen Sie die heap.json Datei in Safaris Developer Tools (oder WebKit GTK)

  1. Öffnen Sie die Developer Tools
  2. Klicken Sie auf "Timeline"
  3. Klicken Sie auf "JavaScript Allocations" im Menü links. Es ist möglicherweise nicht sichtbar, bis Sie auf das Stiftsymbol klicken, um alle Timelines anzuzeigen
  4. Klicken Sie auf "Import" und wählen Sie Ihren Heap-Snapshot JSON

Sobald importiert, sollten Sie etwas wie dieses sehen:

Der Web Debugger bietet ebenfalls die Timeline-Funktion, mit der Sie die Speichernutzung der laufenden Debug-Sitzung verfolgen und untersuchen können.

Native Heap-Statistiken

Bun verwendet mimalloc für den anderen Heap. Um eine Zusammenfassung der Nicht-JavaScript-Speichernutzung zu berichten, setzen Sie die MIMALLOC_SHOW_STATS=1 Umgebungsvariable und Statistiken werden beim Beenden ausgegeben.

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-Profiling

Profilieren Sie die JavaScript-Ausführung, um Performance-Engpässe mit dem --cpu-prof Flag zu identifizieren.

sh
bun --cpu-prof script.js

Dies generiert eine .cpuprofile Datei, die Sie in Chrome DevTools (Performance Tab → Load profile) oder VS Codes CPU Profiler öffnen können.

Optionen

sh
bun --cpu-prof --cpu-prof-name my-profile.cpuprofile script.js
bun --cpu-prof --cpu-prof-dir ./profiles script.js
FlagBeschreibung
--cpu-profProfiling aktivieren
--cpu-prof-name <filename>Output-Dateiname setzen
--cpu-prof-dir <dir>Output-Verzeichnis setzen

Bun von www.bunjs.com.cn bearbeitet