Les boucles de shell sont lentes et les bash sont les plus lentes. Les obus ne sont pas destinés à effectuer un travail lourd en boucles. Les shells sont destinés à lancer quelques processus externes optimisés sur des lots de données.
Quoi qu'il en soit, j'étais curieux de savoir comment les boucles shell se comparent, j'ai donc fait un petit point de repère:
#!/bin/bash
export IT=$((10**6))
echo POSIX:
for sh in dash bash ksh zsh; do
TIMEFORMAT="%RR %UU %SS $sh"
time $sh -c 'i=0; while [ "$IT" -gt "$i" ]; do i=$((i+1)); done'
done
echo C-LIKE:
for sh in bash ksh zsh; do
TIMEFORMAT="%RR %UU %SS $sh"
time $sh -c 'for ((i=0;i<IT;i++)); do :; done'
done
G=$((10**9))
TIMEFORMAT="%RR %UU %SS 1000*C"
echo 'int main(){ int i,sum; for(i=0;i<IT;i++) sum+=i; printf("%d\n", sum); return 0; }' |
gcc -include stdio.h -O3 -x c -DIT=$G -
time ./a.out
(
Détails:
- Processeur: Intel (R) Core (TM) i5 CPU M 430 @ 2,27 GHz
- ksh: version sh (AT&T Research) 93u + 2012-08-01
- bash: GNU bash, version 4.3.11 (1) -release (x86_64-pc-linux-gnu)
- zsh: zsh 5.2 (x86_64-unknown-linux-gnu)
- tiret: 0.5.7-4ubuntu1
)
Les résultats (abrégés) (temps par itération) sont:
POSIX:
5.8 µs dash
8.5 µs ksh
14.6 µs zsh
22.6 µs bash
C-LIKE:
2.7 µs ksh
5.8 µs zsh
11.7 µs bash
C:
0.4 ns C
D'après les résultats:
Si vous voulez une boucle de shell un peu plus rapide, alors si vous avez la [[
syntaxe et que vous voulez une boucle de shell rapide, vous êtes dans un shell avancé et vous avez aussi la boucle for de type C. Utilisez alors la boucle C comme pour. Ils peuvent être environ 2 fois plus rapides que les while [
boucles dans la même coque.
- ksh a la
for (
boucle la plus rapide à environ 2,7 µs par itération
- le tiret a la
while [
boucle la plus rapide à environ 5,8 µs par itération
C pour les boucles peut être de 3 à 4 décimales plus rapide. (J'ai entendu les Torvalds adorer C).
La boucle C optimisée est 56500 fois plus rapide que la while [
boucle de bash (la boucle de shell la plus lente) et 6750 fois plus rapide que la for (
boucle de ksh (la boucle de shell la plus rapide).
Encore une fois, la lenteur des shells ne devrait pas avoir beaucoup d'importance, car le modèle typique des shells consiste à se décharger sur quelques processus de programmes externes optimisés.
Avec ce modèle, les shells facilitent souvent l'écriture de scripts avec des performances supérieures aux scripts python (la dernière fois que j'ai vérifié, créer des pipelines de processus en python était plutôt maladroit).
Une autre chose à considérer est le temps de démarrage.
time python3 -c ' '
prend 30 à 40 ms sur mon PC alors que les obus prennent environ 3 ms. Si vous lancez beaucoup de scripts, cela s'ajoute rapidement et vous pouvez faire beaucoup dans les 27 à 37 ms supplémentaires que python prend juste pour démarrer. Les petits scripts peuvent être terminés plusieurs fois au cours de cette période.
(NodeJs est probablement le pire runtime de script dans ce département car il faut environ 100 ms pour démarrer (même si une fois qu'il a démarré, vous auriez du mal à trouver un meilleur interprète parmi les langages de script)).