Commandes hyperfine
hyperfine est un outil de benchmarking en ligne de commandes écrit en Rust. Il fournit une analyse statistique des temps d’exécution de commandes, gère les exécutions de préchauffage, supporte les benchmarks paramétrés et exporte les résultats dans plusieurs formats.
Installation
Linux/Ubuntu
# Ubuntu/Debian
sudo apt install hyperfine
# Fedora
sudo dnf install hyperfine
# Arch Linux
sudo pacman -S hyperfine
# Cargo (Rust)
cargo install hyperfine
# From GitHub releases
wget https://github.com/sharkdp/hyperfine/releases/latest/download/hyperfine_1.19.0_amd64.deb
sudo dpkg -i hyperfine_1.19.0_amd64.deb
# Verify
hyperfine --version
Benchmarking de base
# Benchmark d'une seule commande
hyperfine 'sleep 0.5'
# Benchmark avec un nombre spécifique d'exécutions
hyperfine --runs 20 'my_command'
# Benchmark avec un nombre minimum d'exécutions
hyperfine --min-runs 50 'my_command'
# Définir le temps minimum de benchmark (secondes)
hyperfine --min-benchmarking-time 10 'my_command'
Comparaison de commandes
# Comparer deux commandes
hyperfine 'find . -name "*.py"' 'fd -e py'
# Comparer plusieurs commandes
hyperfine 'grep -r TODO .' 'rg TODO' 'ag TODO'
# Comparer avec des étiquettes lisibles
hyperfine --command-name 'GNU grep' 'grep -r TODO .' \
--command-name 'ripgrep' 'rg TODO' \
--command-name 'silver searcher' 'ag TODO'
# Comparer les implémentations de tri
hyperfine 'sort large_file.txt' 'sort --parallel=4 large_file.txt'
# Comparer différents compilateurs
hyperfine 'gcc -O2 -o test test.c && ./test' \
'clang -O2 -o test test.c && ./test'
Exécutions de préchauffage
# Exécuter des itérations de préchauffage avant le benchmark (remplit les caches)
hyperfine --warmup 5 'cat large_file.txt | wc -l'
# Le préchauffage est essentiel pour :
# - Réchauffement du cache du système de fichiers
# - Préchauffage de la compilation JIT
# - Population du cache DNS
hyperfine --warmup 10 'curl -s http://localhost:8080/api/data > /dev/null'
# Commande de préparation (exécutée avant chaque benchmark, non chronométrée)
hyperfine --prepare 'sync; echo 3 | sudo tee /proc/sys/vm/drop_caches' \
'cat large_file.txt | wc -l'
Configuration et nettoyage
# Exécuter une commande de configuration avant la suite de benchmarks
hyperfine --setup 'make build' './my_program'
# Exécuter une commande de préparation avant CHAQUE itération (non chronométrée)
hyperfine --prepare 'cp original.txt test.txt' 'sort -o test.txt test.txt'
# Exécuter une commande de nettoyage après chaque itération
hyperfine --cleanup 'rm -f output.txt' 'my_command > output.txt'
# Combiner configuration, préparation et nettoyage
hyperfine \
--setup 'gcc -O2 -o benchmark benchmark.c' \
--prepare 'echo 3 | sudo tee /proc/sys/vm/drop_caches > /dev/null' \
--cleanup 'rm -f /tmp/bench_output' \
'./benchmark > /tmp/bench_output'
Listes de paramètres
# Benchmark avec une plage de valeurs de paramètres
hyperfine --parameter-scan threads 1 8 './my_program --threads {threads}'
# Scan de paramètres avec taille de pas
hyperfine --parameter-scan size 100 1000 --parameter-step-size 100 \
'./process --size {size}'
# Liste de paramètres (valeurs explicites)
hyperfine --parameter-list lang 'python3,node,ruby' '{lang} script.{lang}'
# Listes de paramètres multiples
hyperfine --parameter-list compiler 'gcc,clang' \
--parameter-list opt '0,1,2,3' \
'{compiler} -O{opt} -o test test.c && ./test'
# Benchmark de différentes tailles de fichiers
hyperfine --parameter-list size 'small,medium,large' \
--prepare 'cp data_{size}.csv input.csv' \
'./process input.csv'
Formats d’exportation
# Exporter en JSON (le plus détaillé)
hyperfine --export-json results.json 'my_command'
# Exporter en CSV
hyperfine --export-csv results.csv 'my_command'
# Exporter en tableau Markdown
hyperfine --export-markdown results.md 'command1' 'command2'
# Exporter en AsciiDoc
hyperfine --export-asciidoc results.adoc 'command1' 'command2'
# Exporter dans tous les formats à la fois
hyperfine \
--export-json results.json \
--export-csv results.csv \
--export-markdown results.md \
'command1' 'command2'
# La sortie JSON inclut :
# - Temps moyen, médian, minimum, maximum
# - Écart-type
# - Temps d'exécution individuels
# - Valeurs des paramètres (si utilisés)
Analyse statistique
# Afficher la détection des valeurs aberrantes
hyperfine 'my_command'
# La sortie montre : moyenne, min, max et signale les aberrants
# Augmenter la précision avec plus d'exécutions
hyperfine --runs 100 'my_command'
# Ignorer les premières N exécutions comme aberrants
hyperfine --ignore-failure 'my_command'
# Afficher les temps d'exécution individuels
hyperfine --show-output 'my_command'
# Mesurer le surcoût de démarrage du shell
hyperfine --shell=none 'my_command'
# Utiliser un shell spécifique
hyperfine --shell /bin/bash 'my_command'
hyperfine --shell /bin/zsh 'my_command'
# Sans shell (exécution directe — évite le surcoût du shell)
hyperfine -N './my_binary arg1 arg2'
Contrôle de sortie
# Afficher la sortie de la commande (ne pas supprimer stdout/stderr)
hyperfine --show-output 'echo hello'
# Options de style
hyperfine --style full 'my_command' # Barre de progression complète (défaut)
hyperfine --style basic 'my_command' # Sortie texte simple
hyperfine --style nocolor 'my_command' # Sans couleurs ANSI
hyperfine --style color 'my_command' # Sortie colorée
hyperfine --style none 'my_command' # Sortie minimale
# Trier les résultats par temps moyen
hyperfine --sort mean-time 'cmd1' 'cmd2' 'cmd3'
# Trier par nom de commande
hyperfine --sort command 'cmd1' 'cmd2' 'cmd3'
Exemples concrets
# Comparer les parseurs JSON
hyperfine --warmup 3 \
'python3 -c "import json; json.load(open(\"data.json\"))"' \
'python3 -c "import orjson; orjson.loads(open(\"data.json\",\"rb\").read())"'
# Benchmark de requêtes de base de données
hyperfine --warmup 2 --runs 30 \
'psql -c "SELECT count(*) FROM users" mydb' \
'psql -c "SELECT count(*) FROM users WHERE active = true" mydb'
# Comparer la compression de fichiers
hyperfine --warmup 1 --prepare 'cp original.tar test.tar' \
'gzip test.tar' \
--prepare 'cp original.tar test.tar' \
'zstd test.tar' \
--prepare 'cp original.tar test.tar' \
'lz4 test.tar'
# Benchmark du cache de build Docker
hyperfine --warmup 1 --runs 5 \
'docker build -t test .'
# Comparer les moteurs de regex
hyperfine \
"grep -cP '\d{3}-\d{3}-\d{4}' large_log.txt" \
"rg -c '\d{3}-\d{3}-\d{4}' large_log.txt"
# Benchmark des endpoints HTTP
hyperfine --warmup 5 \
'curl -s http://localhost:8080/api/v1/users > /dev/null' \
'curl -s http://localhost:8080/api/v2/users > /dev/null'
# Tester les performances d'E/S avec cache froid
hyperfine \
--prepare 'sync; echo 3 | sudo tee /proc/sys/vm/drop_caches > /dev/null' \
'cat /path/to/large/file > /dev/null'
Interprétation des résultats
# Exemple de sortie :
# Benchmark 1: fd -e py
# Time (mean +/- sigma): 12.3 ms +/- 1.2 ms [User: 8.1 ms, System: 4.0 ms]
# Range (min ... max): 10.5 ms ... 16.8 ms 50 runs
#
# - mean : temps d'exécution moyen
# - sigma : écart-type (plus bas = plus cohérent)
# - User : temps CPU en mode utilisateur
# - System : temps CPU en mode noyau
# - Range : exécutions la plus rapide et la plus lente
# - "X runs" ont été effectuées pour la significativité statistique
#
# Summary:
# fd -e py ran 12.45 +/- 3.21 times faster than find . -name "*.py"
Référence rapide
| Option | Fonction |
|---|---|
--runs N | Définir le nombre exact d’exécutions de benchmark |
--warmup N | Exécutions de préchauffage avant mesure |
--prepare CMD | Exécuter avant chaque itération de benchmark |
--cleanup CMD | Exécuter après chaque itération de benchmark |
--setup CMD | Exécuter une fois avant toute la suite |
--parameter-scan | Itérer sur une plage numérique |
--parameter-list | Itérer sur des valeurs explicites |
--export-json | Exporter les résultats JSON détaillés |
--export-csv | Exporter les résultats CSV |
--export-markdown | Exporter un tableau Markdown |
--command-name | Étiquette pour l’affichage |
-N / --shell=none | Ignorer le shell, exécuter le binaire directement |
--show-output | Ne pas supprimer stdout/stderr |
--ignore-failure | Continuer avec les codes de sortie non-zéro |