2 puntos por GN⁺ 2025-09-12 | Aún no hay comentarios. | Compartir por WhatsApp
  • La instalación de paquetes de Bun funciona a una velocidad muy superior en comparación con los gestores de paquetes existentes
  • La clave de su rapidez está en un enfoque desde la programación de sistemas y en la minimización de llamadas al sistema
  • Ofrece mejoras de rendimiento mediante estrategias detalladas como código nativo basado en Zig, uso de caché binaria y optimizaciones por sistema operativo
  • Incluso en el proceso de descompresión de tarballs y copia de archivos, adopta métodos de alto rendimiento que aprovechan las características del hardware
  • Mediante la optimización de estructuras de datos como el grafo de dependencias y el lockfile, mejora la eficiencia de la caché de CPU y la accesibilidad a la memoria

Por qué Bun Install es rápido

  • bun install de Bun ofrece, en promedio, un rendimiento de instalación de paquetes 7 veces más rápido que npm, 4 veces más rápido que pnpm y 17 veces más rápido que yarn
  • Esto no se debe solo a un benchmark, sino a que el problema de instalar paquetes fue abordado desde la perspectiva de la programación de sistemas y no desde JavaScript
  • Aplica agresivamente optimizaciones de rendimiento en múltiples capas, como minimización de llamadas al sistema, caché binaria de manifiestos, optimización de extracción de tarballs y copia de archivos nativa del sistema operativo

Límites de Node.js y de la arquitectura de los gestores de paquetes

  • Desde el lanzamiento de Node.js en 2009, el modelo de IO asíncrono basado en event loop y thread pool también se trasladó a los gestores de paquetes
  • En ese momento, debido a las limitaciones del hardware de la época (discos lentos, red lenta), la estrategia de IO asíncrono y alta frecuencia de llamadas al sistema era razonable
  • Sin embargo, en los sistemas modernos ya son comunes los SSD NVMe, redes rápidas y CPUs de alto rendimiento, y el verdadero cuello de botella ya no es el IO, sino el overhead de las llamadas al sistema

El costo de las llamadas al sistema y del cambio de modo

  • Cuando un programa solicita una operación como leer un archivo, debe cambiar de user mode a kernel mode, y este proceso consume costosos ciclos de CPU (1000~1500 cycles)
  • La instalación de paquetes requiere por naturaleza decenas de miles o incluso cientos de miles de llamadas al sistema, por lo que solo el costo de esos cambios puede consumir varios segundos de tiempo de CPU
  • Por ejemplo, al instalar React y sus dependencias, npm usa alrededor de 1 millón de llamadas al sistema, yarn 4 millones, pnpm 500 mil y bun 160 mil

Diferencias de enfoque entre los gestores de paquetes existentes y Bun

  • npm, pnpm y yarn están todos basados en Node.js, por lo que JavaScript debe ejecutarse a través de varias capas de abstracción (libuv, event loop, thread pool, intermediación de llamadas al sistema)
  • En este proceso se acumulan conversiones de argumentos, colas del worker pool, bifurcaciones de tareas del event loop y llamadas al sistema futex (sincronización de locks), lo que termina haciendo que la gestión de llamadas al sistema sea más lenta que el propio IO
  • Un gestor de paquetes hecho con Node.js tiene dificultades para alcanzar un rendimiento cercano al nativo debido a estas limitaciones estructurales

Bun: un motor de instalación nativo implementado en Zig

  • Bun, implementado en Zig, invoca directamente las llamadas al sistema, omitiendo por completo el motor de JavaScript y las capas de abstracción
  • Por ejemplo, la lectura de archivos ejecuta directamente la llamada al sistema openat() desde código Zig y devuelve los datos de inmediato
  • Por eso, el proceso de leer decenas de miles de archivos funciona a altísima velocidad sin pasar por thread pools, event loops ni transformaciones de datos adicionales
  • Según benchmarks, Bun puede leer 146,057 package.json por segundo, mientras que Node.js es más de 2 veces más lento, en el rango de 60 mil

Gestión de dependencias y optimización de DNS

  • Al ejecutar bun install, Bun dispara el análisis de dependencias y el DNS prefetch de manera asíncrona al mismo tiempo
  • Por ejemplo, en macOS usa la API async DNS no oficial de Apple (getaddrinfo_async_start()), lo que permite procesar trabajo de red en paralelo sin bloquear threads
  • Los gestores de paquetes existentes, al basarse en el thread pool de libuv, terminan ejecutando internamente código bloqueante y desperdiciando recursos

Caché binaria de manifiestos de paquetes

  • npm y otros almacenan en caché los manifiestos como JSON, pero Bun los parsea una vez y luego guarda el resultado convertido en binario (archivo .npm)
  • Esto minimiza la duplicación de strings y el overhead de parsing, y en memoria real permite acceder a los valores directamente con cálculos de offsets (sin crear nuevos objetos, sin parsing y sin garbage collection)
  • Con los headers ETag e If-None-Match puede verificar solo los cambios y validar actualidad sin parsear datos innecesarios
  • En benchmarks, la instalación desde caché de Bun es incluso más rápida que una instalación fresh de npm

Rendimiento en el procesamiento de tarballs (archivos comprimidos)

  • Los gestores de paquetes normales reciben el tarball como stream, y cuando falta memoria de buffer se producen continuamente reasignaciones, copias y redimensionamientos
  • Bun recibe el tarball completo antes de descomprimirlo y usa los últimos 4 bytes del gzip para conocer de antemano el tamaño descomprimido, por lo que solo asigna memoria una vez
  • Aprovecha libdeflate y otras técnicas para descompresión rápida, eliminando copias duplicadas innecesarias y cambios de tamaño

Optimización del grafo de dependencias y de las estructuras de datos

  • Los gestores de paquetes existentes construyen árboles de dependencias basados en objetos y punteros de JavaScript, lo que dispersa aleatoriamente la memoria y provoca frecuentes fallos de caché de CPU (problema de pointer chasing)
  • Bun aplica el patrón Structure of Arrays (SoA) para guardar todos los paquetes, strings y dependencias en grandes bloques continuos de memoria
    • Con acceso basado en offsets/longitudes, la CPU puede leer varios paquetes de una vez en unidades de cache line (estructura amigable con la caché)
    • El lockfile también se almacena, en lugar de JSON/YAML, de forma alineada con el patrón SoA, eliminando duplicación de strings y facilitando el acceso secuencial a memoria
  • También introdujo de forma experimental el formato binario de lockfile (bun.lockb), pero luego cambió a un formato de texto plano más legible debido al deterioro en la colaboración con Git

Optimización de copia de archivos por sistema operativo

macOS

  • Uso de clonefile: clona directorios completos en una sola llamada al sistema usando Copy-On-Write
  • Minimiza el uso duplicado de espacio en disco y maximiza la velocidad de instalación
  • Si clonefile falla, aplica un fallback escalonado: clonación por directorio y luego copyfile

Linux

  • Intenta primero hard links: crea una nueva referencia al archivo existente sin generar un archivo nuevo (sin mover datos en disco)
  • Si no se pueden usar hard links, en Btrfs/XFS aplica Copy-On-Write mediante ioctl_ficlone
  • Después hace fallback a copy_file_range, sendfile y finalmente a la copia tradicional con copyfile

Conclusión

  • Bun superó los límites tradicionales de rendimiento de los gestores de paquetes mediante minimización de llamadas al sistema, estructuras binarias, optimización por sistema operativo y mejoras en estructuras de datos
  • Gracias a ello, además de instalaciones ultrarrápidas, también ofrece mejoras en eficiencia de memoria y CPU
  • Puede aplicarse a proyectos sin reemplazar por completo el runtime frente a gestores basados en Node.js (manteniendo compatibilidad)
  • En bases de código grandes, ofrece la experiencia de reducir procesos de instalación que antes tardaban minutos a unos pocos milisegundos o segundos
  • Es un excelente caso de optimización a medida según el sistema, el hardware y el nivel del sistema operativo, con alto valor como referencia e investigación

Aún no hay comentarios.

Aún no hay comentarios.