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:
- Die Web-Standard
performance.now()Funktion Bun.nanoseconds()ähnlich wieperformance.now(), gibt jedoch die aktuelle Zeit seit dem Start der Anwendung in Nanosekunden zurück. Sie könnenperformance.timeOriginverwenden, 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
mitataein 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 wieautocannonsind 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:
import { heapStats } from "bun:jsc";
console.log(heapStats());Beispielstatistiken anzeigen
{
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:
Bun.gc(true); // synchron
Bun.gc(false); // asynchronHeap-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:
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)
- Öffnen Sie die Developer Tools
- Klicken Sie auf "Timeline"
- Klicken Sie auf "JavaScript Allocations" im Menü links. Es ist möglicherweise nicht sichtbar, bis Sie auf das Stiftsymbol klicken, um alle Timelines anzuzeigen
- 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.
MIMALLOC_SHOW_STATS=1 bun script.jsheap 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 MiBCPU-Profiling
Profilieren Sie die JavaScript-Ausführung, um Performance-Engpässe mit dem --cpu-prof Flag zu identifizieren.
bun --cpu-prof script.jsDies generiert eine .cpuprofile Datei, die Sie in Chrome DevTools (Performance Tab → Load profile) oder VS Codes CPU Profiler öffnen können.
Optionen
bun --cpu-prof --cpu-prof-name my-profile.cpuprofile script.js
bun --cpu-prof --cpu-prof-dir ./profiles script.js| Flag | Beschreibung |
|---|---|
--cpu-prof | Profiling aktivieren |
--cpu-prof-name <filename> | Output-Dateiname setzen |
--cpu-prof-dir <dir> | Output-Verzeichnis setzen |