Perfilado de código Rust: encontrando cuellos de botella para principiantes

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿por qué perfilar código Rust?

\n\n

Rust es famoso por su velocidad y seguridad, pero incluso el código más rápido puede funcionar lentamente si tiene cuellos de botella. El perfilado es el proceso de medir el rendimiento de un programa: tiempo de ejecución, carga de la CPU, memoria y otras métricas. Para los desarrolladores principiantes en Rust, esta es una habilidad indispensable que permite convertir código «que simplemente funciona» en código eficiente y rápido.

\n\n

Imagina que has escrito un analizador de registros o un juego en Rust. Todo compila, pero el programa tarda más de lo esperado. En lugar de adivinar qué parte del código está ralentizando, puedes usar perfiladores que mostrarán los «puntos calientes» (hotspots) exactos. En este artículo, analizaremos las herramientas principales de perfilado de Rust para principiantes: cargo-flamegraph, perf y mediciones simples con std::time::Instant.

\n\n

1. La forma más simple: mediciones de tiempo con std::time::Instant

\n\n

Antes de pasar a herramientas complejas, aprende a medir el tiempo de ejecución de secciones individuales de código. Este es un método básico pero efectivo para principiantes.

\n\n

Ejemplo: medir el tiempo de ejecución de una función

\n\n
use std::time::Instant;\n\nfn slow_function() {\n    let mut sum = 0u64;\n    for i in 0..1_000_000 {\n        sum += i;\n    }\n    println!("Suma: {}", sum);\n}\n\nfn main() {\n    let start = Instant::now();\n    slow_function();\n    let duration = start.elapsed();\n    println!("Tiempo de ejecución: {:?}", duration);\n}\n
\n\n

Este código mostrará el tiempo exacto de ejecución de slow_function. Sin embargo, este enfoque no es conveniente para proyectos grandes: tendrías que colocar manualmente las mediciones en cada lugar sospechoso.

\n\n

¿Cuándo es útil esto?

\n
    \n
  • Quieres verificar rápidamente una hipótesis sobre una función lenta.
  • \n
  • No es posible instalar herramientas adicionales.
  • \n
  • Estás trabajando con código de un solo hilo sin lógica compleja.
  • \n
\n\n

Desventaja: las mediciones manuales no muestran cuánto tiempo se gasta dentro de las funciones llamadas (por ejemplo, asignaciones de memoria o llamadas al sistema). Para eso se necesitan perfiladores.

\n\n

2. Perfilado con perf (Linux)

\n\n

La utilidad perf es un potente perfilador para Linux que funciona a nivel de kernel. Recoge muestras (samples) de dónde pasa el tiempo el programa. Para empezar, asegúrate de que perf esté instalado:

\n\n
sudo apt install linux-tools-common linux-tools-generic  # Ubuntu/Debian\n
\n\n

Paso 1: Compilación con información de depuración

\n

Para que perf pueda mostrar nombres de funciones y líneas de código, compila el proyecto en modo debug (o release con las banderas debuginfo):

\n\n
cargo build\n# o\nRUSTFLAGS="-g" cargo build --release\n
\n\n

Paso 2: Iniciar el perfilado

\n
perf record -g ./target/debug/tu_programa\nperf report\n
\n\n

La bandera -g habilita la grabación de la pila de llamadas (call graph). Después de ejecutar perf report, verás una lista interactiva de funciones ordenadas por tiempo de ejecución.

\n\n

Ejemplo de interpretación

\n

Supongamos que ves que el 70% del tiempo lo ocupa la función Vec::push. Esto podría significar que estás reasignando memoria con frecuencia. Solución: reservar la capacidad del vector de antemano con Vec::with_capacity.

\n\n

Consejo: Para principiantes, perf puede parecer complejo debido a la abundancia de datos. Comienza con perf top en tiempo real para ver qué funciones están «ardiendo» en este momento.

\n\n

3. Visualización con cargo-flamegraph

\n\n

Si necesitas una imagen visual, usa cargo-flamegraph. Esta herramienta construye flamegraphs — gráficos donde el ancho del rectángulo muestra el tiempo de ejecución de la función y la profundidad muestra la anidación de llamadas.

Blogs

Book Recommendations