Roc, el lenguaje funcional a 2,6% de la velocidad de C

Un lenguaje funcional a un dígito de C

Roc, un lenguaje de programación funcional que pone la velocidad como prioridad número uno, dejó a su paquete de compresión roc-deflate a solo 2,6% de libdeflate, la biblioteca DEFLATE escrita en C y afinada a mano con instrucciones SIMD. En una máquina AMD Ryzen 9 3900X con Ubuntu, la mediana de la brecha subió a 8,9%. Para cualquier founder que alguna vez sacrificó rendimiento en nombre de la seguridad de memoria, ese número mueve el piso de lo que se creía posible.

¿Qué es Roc y qué se midió exactamente?

Roc es un lenguaje funcional —no un asistente de pruebas como Lean— que se presenta con el lema "Fast, Friendly, Functional". El orden no es casual: tanto correr rápido como compilar rápido fueron objetivos centrales desde el arranque del proyecto. El lenguaje todavía no llegó a su primera versión numerada: 0.1.0 está a semanas de salir, después de ocho años de desarrollo, y su ecosistema de paquetes casi no había recibido trabajo de optimización.

El paquete en cuestión, roc-deflate, lo escribió Niclas Ahden y lo usa en trabajo de producción pago. El autor del análisis invirtió tiempo optimizándolo y después lo midió contra libdeflate usando el clásico corpus Silesia, verificando que ambos produjeran salidas idénticas. Fueron 144 benchmarks, en niveles de compresión L1 a L12, sobre dos equipos: un MacBook Pro M1 de 2021 y el Ryzen 9 3900X. La comparación se limitó a las APIs sin streaming, porque roc-deflate todavía no las implementa.

¿Y esto cómo se aplica en tu negocio?

En CAR, dueños de empresa de Latinoamérica y España usan la tecnología para ser más rentables. Empiezas con una ruta de 7 días y terminas con un sistema funcionando en tu negocio.

👥 Probar 7 días

Los resultados: mediana 8,9% más lento en el Ryzen y 2,6% en el M1. En el peor caso, roc-deflate fue 18% más lento; en el mejor, un poco más de 18% más rápido. Esa dispersión no viene de una optimización mágica: son dos implementaciones distintas y, según el autor, no hay que esperar que roc-deflate gane en promedio.

El antecedente: Lean 4 ya le había ganado a Rust

El punto de partida del análisis fue otro resultado: lean-zip, una biblioteca de compresión escrita en Lean 4, superó a miniz_oxide, el paquete de Rust que según crates.io acumula más de mil millones de descargas. En su configuración más rápida, lean-zip fue 15% más veloz y produjo salidas 8,8% más chicas.

Pero ninguno de los dos pudo con libdeflate. La razón es concreta: libdeflate es una implementación cuidadosamente ajustada con SIMD específico de arquitectura, algo a lo que el código Lean no puede acceder. Ahí es donde entra Roc, que sí apunta al rendimiento de ejecución como objetivo explícito de diseño.

¿Qué compra exactamente esa brecha de rendimiento?

El techo de C sigue siendo más alto. Para cualquier input donde roc-deflate hoy gana, el código C puede cerrar esa diferencia. Lo contrario no se cumple: Roc es memory-safe, hace conteo automático de referencias y verifica límites, y no ofrece ningún mecanismo tipo unsafe de Rust para desactivar esas garantías. El precio de esas garantías es un techo de rendimiento más bajo.

Lo interesante es que el compilador de Roc puede eliminar muchos de esos chequeos cuando demuestra que son seguros, y ahí está buena parte del resultado. Las ventajas concretas de una implementación puramente en Roc, según el análisis:

  • Seguridad de memoria sin escape. El código que causó una vulnerabilidad grave de ejecución remota de código (RCE) en la biblioteca de compresión Brotli no tiene equivalente aquí: no hay operaciones de memoria sin chequear disponibles en el lenguaje.
  • Funciones puras garantizadas por el sistema de tipos. Roc distingue funciones puras con una flecha fina (Bool -> Bool) y funciones con efectos con una flecha gruesa (Bool => Bool). Las anotaciones de roc-deflate solo tienen flechas finas, así que no hay I/O ni acceso arbitrario a memoria.
  • Cadena de suministro acotada. Roc no tiene FFI arbitrario ni scripts de build en los paquetes. Ese último vector fue el que comprometió al popular paquete arrayref de Rust, según relata el autor.
  • Determinismo entre plataformas. Una función pura de Roc devuelve los mismos valores con los mismos argumentos en cualquier target al que compiles, no solo en la misma máquina.

El autor plantea la pregunta al revés, y es la que vale para cualquier equipo técnico: ¿entregarías seguridad de memoria garantizada, ausencia garantizada de efectos secundarios, comportamiento determinista entre plataformas y paquetes sin scripts de build explotables, a cambio de una mejora de velocidad promedio de un solo dígito?

Las optimizaciones que movieron la aguja

La mayoría de las mejoras vinieron de técnicas generales que sirven en cualquier lenguaje. El autor recomienda la serie Performance-Aware Programming de Casey Muratori como material de estudio. Las tácticas específicas de Roc son igual de útiles como referencia mental:

  • Evitar el sharing innecesario. Roc aplica mutación oportunista (lo que Koka llama "functional but in-place"). Para que el compilador pueda mutar en el lugar, los valores tienen que seguir siendo únicos.
  • Elevar los chequeos de límites fuera del loop. No se pueden desactivar los bounds checks, pero sí se pueden volver redundantes: un chequeo previo al loop permite al optimizador borrar los chequeos internos más caros.
  • Construir tablas de búsqueda en tiempo de compilación. Si nada depende de datos en runtime, la evaluación en tiempo de compilación arma la tabla y elimina los chequeos de límites en ejecución.
  • Elegir aritmética con wrap cuando corresponde. plus incluye chequeo de overflow; plus_wrap no. Cuando el compilador no puede probar que no habrá overflow, la segunda opción evita instrucciones extra.

Un detalle de transparencia que vale la pena replicar: el script de benchmark lo generó Claude Opus 5.5 y el autor advierte que no lo auditó por seguridad, así que recomienda correrlo fuera de un sandbox.

¿Qué significa esto para tu startup?

Primero, la advertencia del propio autor: no se puede extrapolar de un solo paquete. roc-deflate concentra el mayor esfuerzo de optimización aplicado a un paquete de Roc hasta la fecha, y todavía no se sabe cuánto generaliza el resultado. Si alguien te vende "reescribamos el backend en un lenguaje funcional y ganamos velocidad", ese argumento no está respaldado por este benchmark.

Dicho eso, hay decisiones que sí puedes tomar hoy:

  • Mide con tu propio corpus antes de migrar. La diferencia entre el peor y el mejor caso fue de 18% más lento a 18% más rápido según el input. Un benchmark sintético no te dice qué pasa con tus datos reales: corre tu propio set y compara salidas byte a byte, como hizo el autor con el corpus Silesia.
  • Trata la cadena de suministro como una métrica de producto. Paquetes sin scripts de build ni FFI arbitrario reducen la superficie de ataque de forma estructural, no por buena voluntad del mantenedor. Si tu equipo depende de cientos de dependencias transitivas, ese es un criterio de selección tan válido como la popularidad del paquete.
  • Audita dónde tienes código sin chequeos de límites. El caso de Brotli muestra que el costo de un bounds check omitido no es teórico. Si tu producto procesa archivos de usuarios, esa es una superficie de riesgo concreta y no un debate de estilo.
  • Separa el lenguaje del runtime. Roc compila a distintos targets y su promesa de determinismo aplica entre plataformas. Si tu equipo opera en varios entornos, la reproducibilidad del comportamiento es un ahorro de tiempo de debugging difícil de medir pero real.

Conclusión

El resultado no dice que los lenguajes funcionales sean más rápidos que C: dice que un lenguaje funcional con recolección automática de memoria, chequeos de límites y funciones puras puede quedar a un solo dígito porcentual de una biblioteca C ajustada a mano con SIMD. Eso no era un resultado que se supiera alcanzable.

Para un founder, la lectura práctica es que el trade-off entre seguridad y rendimiento dejó de ser binario. Antes elegías entre código rápido y código seguro; ahora la pregunta es cuánto estás dispuesto a pagar por las garantías, y la respuesta empieza a ser "menos de lo que pensabas". El propio autor lo resume sin exagerar: es un resultado emocionante, pero no se sabrá cuánto generaliza hasta que se optimicen más bases de código reales en Roc.

Fuentes

¿Y esto cómo se aplica en tu negocio?

En CAR, dueños de empresa de Latinoamérica y España usan la tecnología para ser más rentables. Empiezas con una ruta de 7 días y terminas con un sistema funcionando en tu negocio.

👥 Probar 7 días

Daily Shot: Tu ventaja táctica

Lo que pasó en las últimas 24 horas, resumido para que tú no tengas que filtrarlo.

Suscríbete para recibir cada mañana la curaduría definitiva del ecosistema startup e inversionista. Sin ruido ni rodeos, solo la información estratégica que necesitas para avanzar:

  • Venture Capital & Inversiones: Rondas, fondos y movimientos de capital.
  • IA & Tecnología: Tendencias, Web3 y herramientas de automatización.
  • Modelos de Negocio: Actualidad en SaaS, Fintech y Cripto.
  • Propósito: Erradicar el estancamiento informativo dándote claridad desde tu primer café.

📡 El Daily Shot Startupero

Noticias del ecosistema startup en 2 minutos. Gratis, todos los días.

Share to...