¿Hay algún problema con mi script o Bash es mucho más lento que Python?

Pregunta:

Estaba probando la velocidad de Bash y Python ejecutando un bucle mil millones de veces.

$ cat python.py
#!/bin/python
# python v3.5
i=0;
while i<=1000000000:
    i=i+1;

Código de bash:

$ cat bash2.sh
#!/bin/bash
# bash v4.3
i=0
while [[ $i -le 1000000000 ]]
do
let i++
done

Usando el comando time , descubrí que el código Python tarda solo 48 segundos en completarse, mientras que el código Bash tardó más de 1 hora antes de que matara el script.

¿Por qué esto es tan? Esperaba que Bash fuera más rápido. ¿Hay algún problema con mi script o Bash es mucho más lento con este script?

Respuesta:

Los bucles de shell son lentos y los de bash son los más lentos. Los proyectiles no están destinados a hacer un trabajo pesado en bucles. Los shells están destinados a lanzar algunos procesos externos optimizados en lotes de datos.


De todos modos, tenía curiosidad por saber cómo se comparan los bucles de shell, así que hice un pequeño punto de referencia:

#!/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

( Detalles:

  • CPU: CPU Intel (R) Core (TM) i5 M 430 a 2,27 GHz
  • ksh: versión sh (AT&T Research) 93u + 2012-08-01
  • bash: GNU bash, versión 4.3.11 (1) -release (x86_64-pc-linux-gnu)
  • zsh: zsh 5.2 (x86_64-unknown-linux-gnu)
  • guión: 0.5.7-4ubuntu1

)

Los resultados (abreviados) (tiempo por iteración) son:

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

De los resultados:

Si quieres un ciclo de shell un poco más rápido, entonces si tienes la sintaxis [[ y quieres un ciclo de shell rápido, estás en un shell avanzado y también tienes el ciclo for similar a C. Utilice el ciclo C like for, entonces. Pueden ser aproximadamente 2 veces más rápidos que while [ -loops en el mismo caparazón.

  • ksh tiene el ciclo for ( más rápido a aproximadamente 2,7 µs por iteración
  • dash tiene el ciclo while [ más rápido a aproximadamente 5,8 µs por iteración

C para los bucles puede ser de 3 a 4 órdenes decimales de magnitud más rápido. (Escuché que los Torvalds aman a C).

El bucle C for optimizado es 56500 veces más rápido que el bucle while [ de bash (el bucle de shell más lento) y 6750 veces más rápido que el bucle for ( bucle de ksh) for ( bucle de shell más rápido).


Una vez más, la lentitud de los shells no debería importar mucho, porque el patrón típico con los shells es descargar a unos pocos procesos de programas externos optimizados.

Con este patrón, los shells a menudo facilitan mucho la escritura de scripts con un rendimiento superior al de los scripts de Python (la última vez que lo comprobé, la creación de procesos en Python fue bastante torpe).

Otra cosa a considerar es la hora de inicio.

time python3 -c ' '

tarda de 30 a 40 ms en mi PC, mientras que los shells tardan alrededor de 3 ms. Si inicia una gran cantidad de scripts, esto se suma rápidamente y puede hacer mucho en los 27-37 ms adicionales que Python necesita para comenzar. Los guiones pequeños se pueden terminar varias veces en ese período de tiempo.

(NodeJs es probablemente el peor tiempo de ejecución de secuencias de comandos en este departamento, ya que toma alrededor de 100 ms solo para comenzar (aunque una vez que haya comenzado, sería difícil encontrar un mejor ejecutante entre los lenguajes de secuencias de comandos)).

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top

web tasarım