Qu'est-ce que Criterion et pourquoi l'utiliser ?
Criterion.rs est une bibliothèque puissante et flexible pour le benchmarking (tests de performance) en langage Rust. C'est l'équivalent direct de la célèbre bibliothèque Criterion pour Haskell, mais adaptée à l'écosystème Rust.
Pourquoi utiliser Criterion ? Contrairement aux simples mesures de temps avec std::time::Instant, Criterion offre :
- Analyse statistique : Exécute automatiquement le code de nombreuses fois, collecte un échantillon de temps d'exécution et calcule la moyenne, la médiane, l'écart type et les percentiles.
- Comparaison avec une référence : Permet de comparer les performances de la version actuelle du code avec une version précédente (tests de régression).
- Génération de rapports : Crée de superbes rapports HTML avec graphiques et tableaux.
- Benchmarking paramétrique : Testez facilement les performances d'une fonction avec différentes données d'entrée.
- Résistance au bruit : Les algorithmes de Criterion résistent aux fluctuations de temps d'exécution causées par les processus système en arrière-plan.
Cette bibliothèque est indispensable pour les développeurs qui souhaitent :
- Optimiser les parties critiques de leur code.
- S'assurer que du nouveau code ne ralentit pas les fonctionnalités existantes.
- Prendre des décisions basées sur des données, et non sur des suppositions.
Installation de Criterion dans un projet Rust
Contrairement à Python (pip) ou Node.js (npm), l'installation de bibliothèques en Rust se fait via le gestionnaire de paquets Cargo. Criterion n'est pas une bibliothèque pour le code principal, mais un outil de test. Il faut donc l'ajouter dans la section [dev-dependencies] du fichier Cargo.toml.
Vous devrez également créer un dossier benches/ à la racine de votre projet (à côté de src/).
Étape 1 : Ajoutez la dépendance dans Cargo.toml
[dev-dependencies]
criterion = { version = "0.5", features = ["html_reports"] }
Remarque : Le flag features = ["html_reports"] active la génération de rapports HTML. Sans lui, seuls les résultats textuels dans la console seront disponibles.
Étape 2 : Créez un fichier de benchmark
Créez un fichier benches/my_benchmark.rs (le nom peut être quelconque).
Étape 3 : Lancez le benchmark
cargo bench
Cette commande compile votre projet en mode release (avec optimisations) et exécute tous les benchmarks du dossier benches/.
Démarrage rapide : premier benchmark
Écrivons un benchmark simple qui mesure la vitesse de sommation des nombres de 0 à 99.
// benches/my_benchmark.rs
use criterion::{black_box, criterion_group, criterion_main, Criterion};
// Fonction à tester
fn sum_slow(n: u64) -> u64 {
let mut sum = 0;
for i in 0..n {
sum += i;
}
sum
}
fn sum_fast(n: u64) -> u64 {
n * (n - 1) / 2
}
fn criterion_benchmark(c: &mut Criterion) {
// Regroupement des benchmarks
let mut group = c.benchmark_group("sum_comparison");
group.bench_function("slow", |b| b.iter(|| sum_slow(black_box(100))));
group.bench_function("fast", |b| b.iter(|| sum_fast(black_box(100))));
group.finish();
}
// Macros pour l'enregistrement et l'exécution
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
Que se passe-t-il ici ?
black_box()— indique au compilateur que la valeur doit être transmise "telle quelle", empêchant une optimisation prématurée (le compilateur pourrait calculer la constante à la compilation, faussant ainsi les résultats).b.iter()— la boucle principale du benchmark. Criterion appellera cette closure de nombreuses fois et mesurera le temps.criterion_group!etcriterion_main!— des macros qui
Aussi dans la bibliothèque
Génération de PDF en Kotlin : meilleures bibliothèques et exemples de code
Génération Swagger/OpenAPI pour Go (Golang) : guide complet
Travailler avec les dates en Swift : Foundation, SwiftDate, DateTools (iOS/macOS)