I loop di shell sono lenti e quelli di bash sono i più lenti. Le conchiglie non sono pensate per fare un lavoro pesante nei circuiti. Le shell hanno lo scopo di avviare alcuni processi esterni e ottimizzati su lotti di dati.
Ad ogni modo, ero curioso di confrontare i loop di shell, quindi ho fatto un piccolo punto di riferimento:
#!/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
(
Dettagli:
- CPU: CPU Intel (R) Core (TM) i5 M 430 a 2,27 GHz
- ksh: versione sh (Ricerca AT&T) 93u + 2012-08-01
- bash: GNU bash, versione 4.3.11 (1) -release (x86_64-pc-linux-gnu)
- zsh: zsh 5.2 (x86_64-unknown-linux-gnu)
- trattino: 0,5,7-4ubuntu1
)
I risultati (abbreviati) (tempo per iterazione) sono:
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
Dai risultati:
Se vuoi un loop shell leggermente più veloce, allora se hai la [[
sintassi e vuoi un loop shell veloce, sei in una shell avanzata e hai anche il C-like per loop. Usa quindi la C come per loop. Possono essere circa 2 volte più veloci di while [
-loops nella stessa shell.
- ksh ha il
for (
ciclo più veloce a circa 2,7 µs per iterazione
- trattino ha il
while [
ciclo più veloce a circa 5,8 µs per iterazione
C per i loop può essere 3-4 ordini decimali di grandezza più veloci. (Ho sentito che i Torvald amano C).
Il ciclo C for ottimizzato è 56500 volte più veloce del while [
loop di bash (il loop di shell più lento) e 6750 volte più veloce del for (
loop di ksh (il loop di shell più veloce).
Ancora una volta, la lentezza delle shell non dovrebbe importare molto, perché il modello tipico con le shell è scaricare su alcuni processi di programmi esterni ottimizzati.
Con questo modello, le shell spesso rendono molto più semplice scrivere script con prestazioni superiori agli script Python (l'ultima volta che ho controllato, creare pipeline di processo in Python era piuttosto goffo).
Un'altra cosa da considerare è il tempo di avvio.
time python3 -c ' '
impiega da 30 a 40 ms sul mio PC mentre le shell impiegano circa 3ms. Se avvii molti script, questo si somma rapidamente e puoi fare molto nei 27-37 ms extra che python impiega solo per iniziare. Piccoli script possono essere finiti più volte nello stesso lasso di tempo.
(NodeJs è probabilmente il peggior runtime di scripting in questo dipartimento in quanto ci vogliono circa 100ms solo per iniziare (anche se una volta iniziato, sarebbe difficile trovare un performer migliore tra i linguaggi di scripting)).