SHELL SEQ:
Un moyen utile d’évaluer les performances d’un shell consiste probablement à effectuer de manière répétitive de très petites évaluations simples. Je pense qu’il est important, non seulement de boucler, mais de boucler une entrée , car un shell doit lire <&0
.
Je pensais que cela compléterait les tests déjà publiés par @cuonglm, car il montre les performances d'un processus shell une fois invoquées, par opposition à la sienne, qui montre la rapidité avec laquelle un processus shell se charge. De cette façon, entre nous, nous couvrons les deux côtés de la médaille.
Voici une fonction pour faciliter la démo:
sh_bench() ( #dont copy+paste comments
o=-c sh=$(command -v "$1") ; shift #get shell $PATH; toss $1
[ -z "${sh##*busybox}" ] && o='ash -c' #cause its weird
set -- "$sh" $o "'$(cat <&3)'" -- "$@" #$@ = invoke $shell
time env - "$sh" $o "while echo; do echo; done|$*" #time (env - sh|sh) AC/DC
) 3<<-\SCRIPT
#Everything from here down is run by the different shells
i="${2:-1}" l="${1:-100}" d="${3:-
}"; set -- "\$((n=\$n\${n:++\$i}))\$d" #prep loop; prep eval
set -- $1$1$1$1$1$1$1$1$1$1 #yup
while read m #iterate on input
do [ $(($i*50+${n:=-$i})) -gt "$(($l-$i))" ] || #eval ok?
eval echo -n \""$1$1$1$1$1"\" #yay!
[ $((n=$i+$n)) -gt "$(($l-$i))" ] && #end game?
echo "$n" && exit #and EXIT
echo -n "$n$d" #damn - maybe next time
done #done
#END
SCRIPT #end heredoc
Il incrémente une variable une fois par nouvelle ligne ou, dans le cas d'une légère optimisation, s'il le peut, il incrémente 50 fois par nouvelle ligne. Chaque fois que la variable est incrémentée, elle est imprimée stdout
. Cela se comporte beaucoup comme une sorte de seq
croix nl
.
Et pour que ce soit très clair, voici une set -x;
sortie tronquée après l'avoir insérée juste avant time
dans la fonction ci-dessus:
time env - /usr/bin/busybox ash -c '
while echo; do echo; done |
/usr/bin/busybox ash -c '"'$(
cat <&3
)'"' -- 20 5 busybox'
Donc, chaque shell s'appelle d'abord comme:
env - $shell -c "while echo; do echo; done |..."
... pour générer l'entrée qu'il devra boucler lorsqu'il lira 3<<\SCRIPT
- ou quand le cat
fera quand même. Et de l’autre côté, |pipe
il s’appelle encore comme:
"...| $shell -c '$(cat <<\SCRIPT)' -- $args"
Donc, mis à part l'appel initial à env
(car il cat
est en fait appelé à la ligne précédente) ; aucun autre processus n'est appelé à partir du moment où il est appelé jusqu'à ce qu'il se termine. Au moins, j'espère que c'est vrai.
Avant les chiffres ...
Je devrais prendre quelques notes sur la portabilité.
posh
n'aime pas $((n=n+1))
et insiste sur$((n=$n+1))
mksh
n'a pas printf
intégré dans la plupart des cas. Les tests antérieurs avaient beaucoup de retard - il était invoquant /usr/bin/printf
pour chaque course. D'où ce qui echo -n
précède.
peut-être plus que je m'en souvienne ...
Quoi qu'il en soit, aux chiffres:
for sh in dash busybox posh ksh mksh zsh bash
do sh_bench $sh 20 5 $sh 2>/dev/null
sh_bench $sh 500000 | wc -l
echo ; done
Ça va les avoir tous d'un coup ...
0dash5dash10dash15dash20
real 0m0.909s
user 0m0.897s
sys 0m0.070s
500001
0busybox5busybox10busybox15busybox20
real 0m1.809s
user 0m1.787s
sys 0m0.107s
500001
0posh5posh10posh15posh20
real 0m2.010s
user 0m2.060s
sys 0m0.067s
500001
0ksh5ksh10ksh15ksh20
real 0m2.019s
user 0m1.970s
sys 0m0.047s
500001
0mksh5mksh10mksh15mksh20
real 0m2.287s
user 0m2.340s
sys 0m0.073s
500001
0zsh5zsh10zsh15zsh20
real 0m2.648s
user 0m2.223s
sys 0m0.423s
500001
0bash5bash10bash15bash20
real 0m3.966s
user 0m3.907s
sys 0m0.213s
500001
ARBITRARY = Peut-être OK?
Néanmoins, il s’agit d’un test plutôt arbitraire, mais il teste la lecture des entrées, l’évaluation arithmétique et l’expansion des variables. Peut-être pas complet, mais peut-être près de là.
EDIT de Teresa e Junior : @mikeserv et moi avons effectué de nombreux autres tests (voir notre chat pour plus de détails), et nous avons constaté que les résultats pourraient être résumés comme suit:
- Si vous avez besoin de vitesse, optez pour dash , il est beaucoup plus rapide que tout autre shell et environ 4x plus rapide que bash .
- Alors que busybox shell de peut être beaucoup plus lent que tableau de bord , dans certains tests , il pourrait être plus rapide, car il a beaucoup de ses propres userland, comme
grep
, sed
, sort
, etc., qui ne sont pas autant de fonctionnalités que la GNU utilisée utilitaires, mais peut faire le travail autant.
- Si la vitesse ne vous intéresse pas, ksh (ou ksh93 ) peut être considéré comme le meilleur compromis entre vitesse et fonctionnalités. Sa vitesse est comparable à celle du plus petit mksh , ce qui est bien plus rapide que bash , et présente également des caractéristiques uniques, telles que l' arithmétique en virgule flottante .
- Bien que bash soit réputé pour sa simplicité, sa stabilité et ses fonctionnalités, il était le plus lent de tous les réservoirs dans la plupart de nos tests, et de loin.