Criterion para Rust: guía completa con ejemplos

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

¿Qué es Criterion y para qué sirve?

\n\n

Criterion.rs es una potente y flexible biblioteca para benchmarking (pruebas de rendimiento) en el lenguaje Rust. Es un análogo directo de la popular biblioteca Criterion para Haskell, pero adaptada al ecosistema de Rust.

\n\n

¿Para qué sirve Criterion? A diferencia de las simples mediciones de tiempo con std::time::Instant, Criterion proporciona:

\n
    \n
  • Análisis estadístico: Ejecuta automáticamente el código muchas veces, recopila una muestra de tiempos de ejecución y calcula la media, mediana, desviación estándar y percentiles.
  • \n
  • Comparación con referencia: Permite comparar el rendimiento de la versión actual del código con la anterior (pruebas de regresión).
  • \n
  • Generación de informes: Crea atractivos informes HTML con gráficos y tablas.
  • \n
  • Benchmarking paramétrico: Prueba fácilmente el rendimiento de una función con diferentes datos de entrada.
  • \n
  • Resistencia al ruido: Los algoritmos de Criterion son resistentes a las fluctuaciones en los tiempos de ejecución causadas por procesos del sistema operativo en segundo plano.
  • \n
\n\n

La biblioteca es indispensable para desarrolladores que quieren:

\n
    \n
  • Optimizar secciones críticas del código.
  • \n
  • Asegurarse de que el nuevo código no ralentiza la funcionalidad existente.
  • \n
  • Tomar decisiones basadas en datos, no en suposiciones.
  • \n
\n\n

Instalación de Criterion en un proyecto Rust

\n\n

A diferencia de Python (pip) o Node.js (npm), en Rust la instalación de bibliotecas se realiza a través del gestor de paquetes Cargo. Criterion no es una biblioteca para el código principal, sino una herramienta de pruebas, por lo que se añade en la sección [dev-dependencies] del archivo Cargo.toml.

\n\n

También necesitarás crear un directorio benches/ en la raíz de tu proyecto (junto a src/).

\n\n

Paso 1: Añade la dependencia en Cargo.toml

\n
[dev-dependencies]\ncriterion = { version = "0.5", features = ["html_reports"] }
\n

Nota: La bandera features = ["html_reports"] habilita la generación de informes HTML. Sin ella, solo se mostrarán salidas de texto en la consola.

\n\n

Paso 2: Crea el archivo de benchmark

\n

Crea el archivo benches/my_benchmark.rs (el nombre puede ser cualquiera).

\n\n

Paso 3: Ejecuta el benchmark

\n
cargo bench
\n

Este comando compilará tu proyecto en modo release (con optimizaciones) y ejecutará todos los benchmarks de la carpeta benches/.

\n\n

Inicio rápido: primer benchmark

\n\n

Escribamos un benchmark simple que mida la velocidad de sumar números del 0 al 99.

\n\n
// benches/my_benchmark.rs\nuse criterion::{black_box, criterion_group, criterion_main, Criterion};\n\n// Función que vamos a probar\nfn sum_slow(n: u64) -> u64 {\n    let mut sum = 0;\n    for i in 0..n {\n        sum += i;\n    }\n    sum\n}\n\nfn sum_fast(n: u64) -> u64 {\n    n * (n - 1) / 2\n}\n\nfn criterion_benchmark(c: &mut Criterion) {\n    // Agrupamos los benchmarks\n    let mut group = c.benchmark_group("sum_comparison");\n    \n    group.bench_function("slow", |b| b.iter(|| sum_slow(black_box(100))));\n    group.bench_function("fast", |b| b.iter(|| sum_fast(black_box(100))));\n    \n    group.finish();\n}\n\n// Macros para registrar y ejecutar\ncriterion_group!(benches, criterion_benchmark);\ncriterion_main!(benches);
\n\n

¿Qué está pasando aquí?

\n
    \n
  • black_box() — le indica al compilador que el valor debe pasarse "tal cual", evitando la optimización prematura (el compilador podría calcular la constante en tiempo de compilación, lo que distorsionaría el resultado).
  • \n
  • b.iter() — el bucle principal del benchmark. Criterion llamará a este closure muchas veces y medirá el tiempo.
  • \n
  • <

Recommendations