El crate bzip2 cambia de C a Rust al 100%
(trifectatech.org)- El crate de bzip2 reemplazó su dependencia de código C con una implementación 100% en Rust
- El rendimiento mejora en general frente a antes, y la compilación cruzada se vuelve más sencilla
- La implementación en Rust mejora tanto la velocidad de compresión como la de descompresión frente a la versión en C
- Los problemas de dependencias de bibliotecas, como los conflictos de símbolos, se reducen considerablemente
- Tras una auditoría de seguridad, se corrigieron errores lógicos importantes, validando su estabilidad
Lanzamiento de bzip2 crate 0.6.0 y transición a Rust
- Hoy se publicó bzip2 versión 0.6.0
- Ahora usa por defecto libbz2-rs-sys, una implementación del algoritmo bzip2 basada en Rust y desarrollada internamente
- Con este cambio, el crate bzip2 es más rápido y la compilación cruzada se volvió más fácil
- El crate libbz2-rs-sys también puede compilarse como una biblioteca dinámica en C. Gracias a esto, los proyectos en C también pueden aprovechar las mejoras de rendimiento
¿Por qué se hizo este cambio?
- El algoritmo bzip2 fue creado en los años 90 y, aunque hoy ya no se usa tanto, sigue siendo necesario en varios protocolos y bibliotecas para cumplir con la especificación
- Muchos proyectos dependen de bzip2, no de forma directa, sino en alguna parte profunda de su árbol de dependencias
- Con base en la experiencia acumulada en zlib-rs, esta vez modernizamos la implementación de bzip2
- Los detalles de implementación de libbz2-rs-sys se trataron en una entrada anterior del blog. Aquí revisamos las ventajas de esta transición
Mejor rendimiento
- La implementación en Rust muestra en general un rendimiento superior al de la versión en C
- En algunos casos el rendimiento es equivalente, pero no hay casos en que sea más lenta
- Rendimiento de compresión: en bzip2 existe la opción
level, pero su impacto en el rendimiento es mínimo - Según las pruebas, en archivos de muestra representativos la versión en Rust logró mejoras de velocidad de más del 10%
Compresión:
| Archivo | C (ciclos de ejecución) | Rust (ciclos de ejecución) | Cambio relativo |
|---|---|---|---|
| sample3.ref (level 1) | 38.51M | 33.53M | -14.87% |
| silesia-small.tar (level 1) | 3.43G | 3.00G | -14.30% |
| silesia-small.tar (level 9) | 3.47G | 3.17G | -9.66% |
En descompresión también mostró mejores resultados en todos los casos:
| Archivo | C (ciclos de ejecución) | Rust (ciclos de ejecución) | Cambio relativo |
|---|---|---|---|
| sample3.bz2 | 2.53M | 2.42M | -4.48% |
| sample1.bz2 | 9.63M | 8.86M | -8.63% |
| sample2.bz2 | 20.47M | 19.02M | -7.67% |
| dancing-color.ps.bz2 | 87.46M | 83.16M | -5.17% |
| re2-exhaustive.txt.bz2 | 1.89G | 1.76G | -7.65% |
| zip64support.tar.bz2 | 2.32G | 2.11G | -10.00% |
Sin embargo, en entornos macOS a veces se observan variaciones en las cifras de descompresión. Fue difícil analizarlas por las limitaciones de las herramientas de medición de rendimiento
Soporte para compilación cruzada
- La compilación cruzada de proyectos Rust con dependencias en C suele funcionar bien gracias al crate
cc, pero cuando falla es muy difícil de depurar - En el proceso de enlazado con bibliotecas del sistema es fácil que aparezcan problemas inesperados, y en algunos entornos, incluyendo compilaciones para WebAssembly, esto se convierte en un obstáculo real
- Al cambiar a una implementación en Rust, los problemas relacionados con C desaparecen por completo
- Ahora es posible compilar de forma cruzada para Windows, Android, WebAssembly y otros entornos sin casos especiales
- Esto es una gran ventaja no solo para la experiencia de usuario, sino también desde la perspectiva de mantenimiento
Sin conflictos de símbolos (export) por defecto
- En las dependencias en C, es necesario exportar símbolos desde bloques externos a Rust, por lo que puede haber conflictos si otra dependencia exporta los mismos símbolos
- libbz2-rs-sys está diseñado para no exportar símbolos por defecto
- Por eso no deberían surgir conflictos de símbolos con otras bibliotecas externas. Si hace falta, la exportación puede activarse con un feature flag
Ejecución de pruebas basadas en MIRI
- Para implementar bzip2 con alto rendimiento en Rust, el uso de código
unsafees inevitable, y también se necesita bastanteunsafepara replicar la interfaz en C - Afortunadamente, este código puede ejecutarse y probarse en un entorno MIRI
- Más aún, las bibliotecas o aplicaciones de nivel superior que usan bzip2 ahora también pueden ejecutar pruebas con MIRI
Conclusión
Ahora el crate bzip2 es más rápido. Ofrece de forma natural una mejor experiencia, hasta el punto de que ya no hace falta preocuparse por ello
1 comentarios
Comentarios en Hacker News