SHELL SEQ:
Probabilmente un utile mezzo per contrassegnare le prestazioni di una shell è fare ripetutamente molte piccole e semplici valutazioni. È importante, penso, non solo eseguire il loop, ma eseguire il loop su input , perché una shell deve leggere <&0
.
Ho pensato che ciò avrebbe integrato i test già pubblicati da @cuonglm perché dimostra una volta invocata la prestazione di un singolo processo shell, a differenza della sua che dimostra la velocità con cui un processo shell viene caricato quando viene invocato. In questo modo, tra di noi, copriamo entrambi i lati della medaglia.
Ecco una funzione per facilitare la demo:
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
Aumenta una variabile una volta per lettura della nuova riga o, se possibile, una leggera ottimizzazione, aumenta di 50 volte per lettura della nuova riga. Ogni volta che la variabile viene incrementata, viene stampata stdout
. Si comporta molto come una specie di seq
croce nl
.
E solo per chiarire cosa fa - ecco un set -x;
output troncato dopo averlo inserito poco prima time
nella funzione sopra:
time env - /usr/bin/busybox ash -c '
while echo; do echo; done |
/usr/bin/busybox ash -c '"'$(
cat <&3
)'"' -- 20 5 busybox'
Quindi ogni shell viene prima chiamata come:
env - $shell -c "while echo; do echo; done |..."
... per generare l'input che dovrà ricorrere al loop quando legge 3<<\SCRIPT
- o quando lo cat
fa, comunque. E dall'altra parte |pipe
si chiama di nuovo come:
"...| $shell -c '$(cat <<\SCRIPT)' -- $args"
Quindi a parte la chiamata iniziale a env
(perché in cat
realtà viene chiamata nella riga precedente) ; nessun altro processo viene invocato dal momento in cui viene chiamato fino alla sua uscita. Almeno spero sia vero.
Prima dei numeri ...
Dovrei prendere alcune note sulla portabilità.
posh
non gli piace $((n=n+1))
e insiste$((n=$n+1))
mksh
non ha un printf
builtin nella maggior parte dei casi. I test precedenti avevano avuto un notevole ritardo, invocandolo /usr/bin/printf
per ogni corsa. Da qui il echo -n
sopra.
forse di più come me lo ricordo ...
Ad ogni modo, ai numeri:
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
Li faranno tutti in una volta sola ...
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 = FORSE OK?
Tuttavia, questo è un test piuttosto arbitrario, ma verifica input di lettura, valutazione aritmetica ed espansione variabile. Forse non completo, ma forse vicino a lì.
EDIT di Teresa e Junior : @mikeserv e io abbiamo fatto molti altri test (vedi la nostra chat per i dettagli), e abbiamo scoperto che i risultati potrebbero essere riassunti in questo modo:
- Se hai bisogno di velocità, vai sicuramente con il trattino , è molto più veloce di qualsiasi altra shell e circa 4x più veloce di bash .
- Mentre busybox shell 's può essere molto più lento rispetto cruscotto , in alcuni test potrebbe essere più veloce, perché ha molte delle sue utility userland, come
grep
, sed
, sort
, ecc, che non hanno molte caratteristiche come la GNU comunemente usato utilità, ma può fare altrettanto.
- Se la velocità non è tutto ciò che ti interessa, ksh (o ksh93 ) può essere considerato il miglior compromesso tra velocità e funzionalità. La sua velocità è paragonabile al mksh più piccolo , che è molto più veloce di bash , e ha anche alcune caratteristiche uniche, come l' aritmetica in virgola mobile .
- Sebbene bash sia famoso per la sua semplicità, stabilità e funzionalità, è stato il più lento di tutti i gusci nella maggior parte dei nostri test e con un ampio margine.