Release
- Cargo tiene 4 perfiles integrados:
dev,release,testybench. - El perfil se selecciona automáticamente en función del comando que se esté ejecutando si no se especifica uno en la línea de comandos.
- Cargo solo revisa la configuración del perfil en el
Cargo.tomlen la raíz del espacio de trabajo. - Se ignorarán las configuraciones de perfil definidas en las dependencias.
Resumen
Release personalizado
Cargo.toml
[dependencies]
mimalloc = "0.1.46"
[profile.release]
# Maximizar la velocidad de ejecución
codegen-units = 1 # Unidades de código para paralelizar la compilación
lto = "fat" # Análisis a nivel de programa en todo el código
# Minimizar el tamaño del binario
panic = "abort" # Cierra el programa en caso de pánico
strip = "symbols" # Elimina la información de depuración y símbolos
.cargo/config.toml
# (Release) Performance
rustflags = ["-C", "target-cpu=native"]
src/main.rs
// ...
#[global_allocator]
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
#[tokio::main]
async fn main() {}
Dockerfile
Si se utiliza mimalloc u otros crates como sqlx y rustls que necesitan gcc o musl-tools
# ...
RUN apt-get update && apt-get install -y musl-tools && rm -rf /var/lib/apt/lists/*
# RUN rustup target add x86_64-unknown-linux-musl
# ...
Release por defecto
- Se utiliza por
cargo install
[profile.release]
opt-level = 3
debug = false
split-debuginfo = '...' # Platform-specific.
strip = "none"
debug-assertions = false
overflow-checks = false
lto = false
panic = 'unwind'
incremental = false
codegen-units = 16
rpath = false
Valores que no se modificaron:
[profile.release]
opt-level = 3 # Runtime
debug = false # Runtime
split-debuginfo = '...'
debug-assertions = false # Runtime
overflow-checks = false # Runtime
incremental = false # Buildd
rpath = false # Runtime
Optimizaciones para performance
codegen-units
Determina en cuántas "unidades de generación de código" se dividirá un crate (para paralelizar y acelerar la compilación. Sin embargo, esta división impide que el optimizador realice un análisis global, lo que puede degradar el rendimiento del binario.
- Esta opción toma un número entero mayor que 0.
- El valor predeterminado es 256 para compilaciones incrementales y 16 para compilaciones no incrementales.
lto
LTO permite que el optimizador de LLVM realice análisis a nivel de programa en todo el código, lo que suele generar binarios más rápidos y, en muchos casos, más pequeños a costa de un mayor tiempo de enlace.
Las opciones válidas son:
false: Realiza una "LTO local thin" que realiza una LTO thin en el contenedor local solo en sus unidades de generación de código . No se realiza una LTO si las unidades de generación de código son 1 o el nivel de opción es 0.trueo"fat": Realiza una LTO “fat” que intenta realizar optimizaciones en todas las cajas dentro del gráfico de dependencia."thin": Realiza una LTO "fina" . Es similar a la "fat", pero tarda mucho menos en ejecutarse y, al mismo tiempo, logra mejoras de rendimiento similares a las de la "fat"."off": Desactiva LTO.
opt-level
- Un nivel de optimización más alto puede generar un código más rápido en tiempo de ejecución, a costa de tiempos de compilación más largos.
- Además, un nivel más alto puede modificar y reorganizar el código compilado, lo que dificulta su uso con un depurador.
- Es recomendable probar con varios ajustes, a veces, 3 podría ser más lento que 2 o que s o z no sean necesariamente binarios más pequeños
Opciones:
0: sin optimizaciones1: optimizaciones básicas2: algunas optimizaciones3: todas las optimizaciones (por defecto)"s": optimizar para tamaño binario"z": optimiza para tamaño binario, pero también desactiva la vectorización de bucle.
overflow-checks
La configuración overflow-checks controla si Rust verifica los desbordamientos aritméticos en operaciones con enteros en tiempo de ejecución.
Para aplicaciones donde la seguridad y la precisión son críticas (como sistemas financieros o médicos), se podría mantener las verificaciones incluso en release, aceptando la pequeña penalización de rendimiento.
Cuando overflow-checks = true:
- El programa entrará en pánico (crash controlado) si ocurre un desbordamiento de entero
- Esto ayuda a detectar errores que podrían causar comportamientos inesperados
- Es muy útil durante el desarrollo y depuración
Cuando overflow-checks = false:
- Los desbordamientos ocurren silenciosamente, siguiendo el comportamiento de "wrapping" (dar la vuelta)
- Por ejemplo, para un u8, 255 + 1 = 0
- Esto suele dar mejor rendimiento porque elimina las verificaciones
- El valor predeterminado es
falsepara maximizar el rendimiento
Optimizaciones para tamaño del binario
panic
Por defecto, el pánico se maneja con “unwind”, lo que permite capturar y manejar errores, pero añade un coste extra en el tamaño y en el rendimiento.
Las opciones válidas son:
"unwind":Desenrolle la pila en caso de pánico."abort":Terminar el proceso en caso de pánico.
Cuando se establece en "unwind", el valor real depende del valor predeterminado de la plataforma de destino. Por ejemplo, la plataforma NVPTX no admite el desenrollado, por lo que siempre usa "abort".
Con "abort" establece que, ante un pánico, el programa aborta inmediatamente, en lugar de realizar la "desenrollado" de la pila, lo cual reduce overhead.
strip
Indica a rustc que elimine los símbolos o la información de depuración de un binario.
Opciones:
"none"ofalse, predeterminado"debuginfo", elimina la información de depuración del binario."symbols"otrue, elimina la información de depuración y símbolos de la tabla de símbolos.
debug
Controla la cantidad de información de depuración incluida en el binario compilado.
Opciones:
0,false, o"none": ninguna información de depuración, valor predeterminado pararelease"line-directives-only": Solo directivas de información de línea."line-tables-only": Solo tablas de líneas. Genera la información de depuración mínima para los seguimientos con información de nombre de archivo/número de línea, pero nada más; es decir, no incluye información de variables ni parámetros de función.1o"limited": información de depuración sin información de tipo ni de variable. Genera información más detallada a nivel de módulo queline-tables-only.2,true, o"full": información de depuración completa, predeterminada paradev
split-debuginfo
Controla si la información de depuración, si se genera, se coloca en el mismo ejecutable o junto a él.
El valor predeterminado para esta opción es unpacked en macOS para los perfiles que tienen habilitada la información de depuración.
Opciones:
-
offEsta es la opción predeterminada para plataformas con binarios ELF y windows-gnu (no Windows MSVC ni macOS). Esto suele significar que la información de depuración de DWARF se puede encontrar en el artefacto final, en secciones del ejecutable. Esta opción no es compatible con Windows MSVC. En macOS, esta opción impide la ejecución final paradsymutilgenerar información de depuración. -
packedEsta es la configuración predeterminada para Windows MSVC y macOS. El término "packed" significa que toda la información de depuración se empaqueta en un archivo separado del ejecutable principal. En Windows MSVC, es un archivo*.pdb; en macOS, una carpeta*.dSYM; y en otras plataformas, un archivo*.dwp. -
unpackedEsto significa que la información de depuración se encontrará en archivos separados para cada unidad de compilación (archivo de objeto). Esto no es compatible con MSVC para Windows. En macOS, esto significa que los archivos de objeto originales contendrán información de depuración. En otras plataformas Unix, esto significa que los archivos*.dwocontendrán información de depuración.
Otros
debug-assertions
Activa o desactiva la compilación condicional cfg(debug_assertions). Las aserciones de depuración incluyen la validación en tiempo de ejecución, disponible únicamente en compilaciones de depuración y desarrollo.
Estas pueden ser funciones demasiado costosas o indeseables en una versión de lanzamiento. Las aserciones de depuración habilitan la macro debug_assert! en la biblioteca estándar.
Cuando debug-assertions = true:
- Habilita la macro
debug_assert!de la biblioteca estándar - Activa código condicional marcado con
cfg(debug_assertions) - Permite validaciones adicionales que solo se ejecutan durante desarrollo
Cuando debug-assertions = false:
- Las macros
debug_assert!no hacen nada (se eliminan en tiempo de compilación) - El código condicional con
cfg(debug_assertions)no se incluye - Elimina estas verificaciones adicionales para mejorar el rendimiento
- El valor predeterminado es
falsepara maximizar el rendimiento
incremental
Habilita o no la compilación incremental. La compilación incremental hace que rustc guarde información adicional en el disco, que se reutilizará al recompilar el paquete, lo que reduce los tiempos de re-compilación. Esta información adicional se almacena en el directorio target.
Las opciones válidas son:
true: activadofalse: desactivado
La compilación incremental solo se utiliza para miembros del espacio de trabajo y dependencias de “ruta”.
rpath
- Incrusta una "ruta de tiempo de ejecución" (runtime path) en el ejecutable
- Esta ruta indica al cargador de programas dónde buscar las bibliotecas compartidas en tiempo de ejecución
- Permite que el ejecutable encuentre dependencias de bibliotecas compartidas en ubicaciones relativas a su propio directorio
Memalloc
- Util para código asíncrono
- Recomendado al usar Tokio
- Recomendado al compilar en
musl
Instalar
cargo add mimalloc
Usar
// ...
#[global_allocator]
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
#[tokio::main]
async fn main() {}
Configuraciones
[build]
# Performance ===========================================
# Optimización para la CPU nativa
# Sin embargo, esto puede causar problemas de portabilidad
rustflags = ["-C", "target-cpu=native"]
# Para tiempos de compilación más cortos ===============
# Usando mold linker
# Util para compilaciones de debug
# Se debe tener instalado mold
# Solo funciona en Linux y macOS
# rustflags = ["-C", "link-arg=-fuse-ld=mold"]
# Para binarios más pequeños ==========================
# No guardar información del código fuente en el binario
# Requiere features inestables
# rustflags = ["-Z", "location-detail=none"]