Bun est conçu pour la vitesse. Les chemins critiques sont largement profilés et benchmarkés. Le code source de tous les benchmarks publics de Bun se trouve dans le répertoire /bench du dépôt Bun.
Mesurer le temps
Pour mesurer précisément le temps, Bun offre deux fonctions d'API runtime :
- La fonction standard Web
performance.now() Bun.nanoseconds()qui est similaire àperformance.now()sauf qu'elle retourne le temps actuel depuis le démarrage de l'application en nanosecondes. Vous pouvez utiliserperformance.timeOriginpour convertir cela en timestamp Unix.
Outils de benchmarking
Lors de l'écriture de vos propres benchmarks, il est important de choisir le bon outil.
- Pour les microbenchmarks, un excellent outil polyvalent est
mitata. - Pour les tests de charge, vous devez utiliser un outil de benchmarking HTTP qui est au moins aussi rapide que
Bun.serve(), sinon vos résultats seront faussés. Certains outils de benchmarking populaires basés sur Node.js commeautocannonne sont pas assez rapides. Nous recommandons l'un des suivants : - Pour benchmarker des scripts ou des commandes CLI, nous recommandons
hyperfine.
Mesurer l'utilisation de la mémoire
Bun a deux tas. Un tas est pour le runtime JavaScript et l'autre tas est pour tout le reste.
Statistiques du tas JavaScript
Le module bun:jsc expose quelques fonctions pour mesurer l'utilisation de la mémoire :
import { heapStats } from "bun:jsc";
console.log(heapStats());Voir des statistiques d'exemple">
{
heapSize: 1657575,
heapCapacity: 2872775,
extraMemorySize: 598199,
objectCount: 13790,
protectedObjectCount: 62,
globalObjectCount: 1,
protectedGlobalObjectCount: 1,
// Un comptage de chaque type d'objet dans le tas
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
}
}Le JavaScript est un langage avec garbage collector, pas avec comptage de références. Il est normal et correct que les objets ne soient pas libérés immédiatement dans tous les cas, bien qu'il ne soit pas normal que les objets ne soient jamais libérés.
Pour forcer l'exécution du garbage collection manuellement :
Bun.gc(true); // synchrone
Bun.gc(false); // asynchroneLes instantanés du tas vous permettent d'inspecter quels objets ne sont pas libérés. Vous pouvez utiliser le module bun:jsc pour prendre un instantané du tas puis le visualiser avec les outils de développement Safari ou WebKit GTK. Pour générer un instantané du tas :
import { generateHeapSnapshot } from "bun";
const snapshot = generateHeapSnapshot();
await Bun.write("heap.json", JSON.stringify(snapshot, null, 2));Pour visualiser l'instantané, ouvrez le fichier heap.json dans les outils de développement de Safari (ou WebKit GTK)
- Ouvrez les outils de développement
- Cliquez sur "Timeline"
- Cliquez sur "JavaScript Allocations" dans le menu de gauche. Il pourrait ne pas être visible jusqu'à ce que vous cliquiez sur l'icône de crayon pour afficher toutes les timelines
- Cliquez sur "Import" et sélectionnez votre JSON d'instantané du tas
Une fois importé, vous devriez voir quelque chose comme ceci :
Le débogueur web offre également la fonctionnalité timeline qui vous permet de suivre et d'examiner l'utilisation de la mémoire de la session de débogage en cours d'exécution.
Statistiques du tas natif
Bun utilise mimalloc pour l'autre tas. Pour afficher un résumé de l'utilisation de la mémoire non-JavaScript, définissez la variable d'environnement MIMALLOC_SHOW_STATS=1 et les statistiques seront affichées à la sortie.
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 MiBProfilage CPU
Profilez l'exécution JavaScript pour identifier les goulots d'étranglement de performance avec le drapeau --cpu-prof.
bun --cpu-prof script.jsCela génère un fichier .cpuprofile que vous pouvez ouvrir dans Chrome DevTools (onglet Performance → Charger le profil) ou le profileur CPU de VS Code.
Options
bun --cpu-prof --cpu-prof-name my-profile.cpuprofile script.js
bun --cpu-prof --cpu-prof-dir ./profiles script.js| Drapeau | Description |
|---|---|
--cpu-prof | Activer le profilage |
--cpu-prof-name <filename> | Définir le nom du fichier de sortie |
--cpu-prof-dir <dir> | Définir le répertoire de sortie |