Os loops de shell são lentos e os do bash são os mais lentos. Os reservatórios não devem fazer trabalho pesado em loops. Os shells destinam-se a iniciar alguns processos externos otimizados em lotes de dados.
Enfim, fiquei curioso para comparar os loops de shell, então fiz um pequeno benchmark:
#!/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
(
Detalhes:
- Processador: CPU Intel (R) Core (i) i5 M 430 a 2,27 GHz
- ksh: versão sh (AT&T Research) 93u + 01/08/2012
- bash: GNU bash, versão 4.3.11 (1) -release (x86_64-pc-linux-gnu)
- zsh: zsh 5.2 (x86_64-unknown-linux-gnu)
- traço: 0.5.7-4ubuntu1
)
Os resultados (abreviados) (tempo por iteração) são:
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
Dos resultados:
Se você deseja um loop de shell um pouco mais rápido, se possui a [[
sintaxe e deseja um loop de shell rápido, está em um shell avançado e também possui o loop for tipo C. Use C como for loop, então. Eles podem ser cerca de 2 vezes mais rápidos que os while [
loops no mesmo shell.
- O ksh tem o
for (
loop mais rápido em cerca de 2,7 µs por iteração
- o traço tem o
while [
loop mais rápido, com cerca de 5,8 µs por iteração
C para loops pode ser de 3 a 4 ordens decimais de magnitude mais rápido. (Eu ouvi os Torvalds amarem C).
O loop C for otimizado é 56500 vezes mais rápido que o while [
loop do bash (o loop de shell mais lento) e 6750 vezes mais rápido que o for (
loop de ksh (o loop de shell mais rápido).
Novamente, a lentidão dos shells não deve importar muito, porque o padrão típico dos shells é descarregar para alguns processos de programas externos otimizados.
Com esse padrão, os shells geralmente tornam muito mais fácil escrever scripts com desempenho superior aos scripts python (da última vez que verifiquei, a criação de pipelines de processos em python era bastante desajeitada).
Outra coisa a considerar é o tempo de inicialização.
time python3 -c ' '
leva de 30 a 40 ms no meu PC, enquanto as conchas demoram cerca de 3ms. Se você lança muitos scripts, isso se soma rapidamente e você pode fazer muito nos 27 a 37 ms extras que o python leva apenas para iniciar. Pequenos scripts podem ser concluídos várias vezes nesse período.
(O NodeJs é provavelmente o pior tempo de execução de script nesse departamento, pois leva cerca de 100 ms apenas para iniciar (mesmo que, uma vez iniciado, seja difícil encontrar um melhor desempenho entre as linguagens de script)).