Bun está diseñado para la velocidad. Las rutas críticas están extensamente perfiladas y evaluadas mediante benchmarking. El código fuente de todos los benchmarks públicos de Bun se encuentra en el directorio /bench del repositorio de Bun.
Medición del tiempo
Para medir el tiempo con precisión, Bun ofrece dos funciones de API de tiempo de ejecución:
- La función estándar web
performance.now() Bun.nanoseconds()que es similar aperformance.now()excepto que devuelve el tiempo actual desde que se inició la aplicación en nanosegundos. Puedes usarperformance.timeOriginpara convertir esto a una marca de tiempo Unix.
Herramientas de benchmarking
Al escribir tus propios benchmarks, es importante elegir la herramienta adecuada.
- Para microbenchmarks, una herramienta de propósito general excelente es
mitata. - Para pruebas de carga, debes usar una herramienta de benchmarking HTTP que sea al menos tan rápida como
Bun.serve(), o tus resultados estarán sesgados. Algunas herramientas de benchmarking populares basadas en Node.js comoautocannonno son lo suficientemente rápidas. Recomendamos una de las siguientes: - Para benchmarks de scripts o comandos CLI, recomendamos
hyperfine.
Medición del uso de memoria
Bun tiene dos heaps. Un heap es para el runtime de JavaScript y el otro heap es para todo lo demás.
Estadísticas del heap de JavaScript
El módulo bun:jsc expone algunas funciones para medir el uso de memoria:
import { heapStats } from "bun:jsc";
console.log(heapStats());Ver estadísticas de ejemplo
{
heapSize: 1657575,
heapCapacity: 2872775,
extraMemorySize: 598199,
objectCount: 13790,
protectedObjectCount: 62,
globalObjectCount: 1,
protectedGlobalObjectCount: 1,
// Un conteo de cada tipo de objeto en el 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 es un lenguaje con recolección de basura, no con conteo de referencias. Es normal y correcto que los objetos no se liberen inmediatamente en todos los casos, aunque no es normal que los objetos nunca se liberen.
Para forzar la ejecución manual de la recolección de basura:
Bun.gc(true); // síncrono
Bun.gc(false); // asíncronoLas instantáneas del heap te permiten inspeccionar qué objetos no se están liberando. Puedes usar el módulo bun:jsc para tomar una instantánea del heap y luego verla con las herramientas de desarrollo de Safari o WebKit GTK. Para generar una instantánea del heap:
import { generateHeapSnapshot } from "bun";
const snapshot = generateHeapSnapshot();
await Bun.write("heap.json", JSON.stringify(snapshot, null, 2));Para ver la instantánea, abre el archivo heap.json en las Herramientas de Desarrollo de Safari (o WebKit GTK)
- Abre las Herramientas de Desarrollo
- Haz clic en "Timeline"
- Haz clic en "JavaScript Allocations" en el menú de la izquierda. Puede que no sea visible hasta que hagas clic en el ícono del lápiz para mostrar todas las líneas de tiempo
- Haz clic en "Import" y selecciona tu instantánea del heap en JSON
Una vez importada, deberías ver algo como esto:
El depurador web también ofrece la función de timeline que te permite rastrear y examinar el uso de memoria de la sesión de depuración en ejecución.
Estadísticas del heap nativo
Bun usa mimalloc para el otro heap. Para reportar un resumen del uso de memoria no JavaScript, establece la variable de entorno MIMALLOC_SHOW_STATS=1 y las estadísticas se imprimirán al salir.
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 MiBPerfilado de CPU
Perfilaa la ejecución de JavaScript para identificar cuellos de botella de rendimiento con la bandera --cpu-prof.
bun --cpu-prof script.jsEsto genera un archivo .cpuprofile que puedes abrir en Chrome DevTools (pestaña Rendimiento → Cargar perfil) o en el perfilador de CPU de VS Code.
Opciones
bun --cpu-prof --cpu-prof-name my-profile.cpuprofile script.js
bun --cpu-prof --cpu-prof-dir ./profiles script.js| Bandera | Descripción |
|---|---|
--cpu-prof | Habilitar perfilado |
--cpu-prof-name <filename> | Establecer nombre del archivo de salida |
--cpu-prof-dir <dir> | Establecer directorio de salida |