Python vs Bash: ¿en qué tipo de tareas cada uno supera al otro en cuanto a rendimiento?

97

Obviamente, Python es más fácil de usar, una búsqueda rápida en Google muestra muchos resultados que dicen que, como Python está compilado por bytes, generalmente es más rápido. Incluso encontré esto que afirma que puede ver una mejora de más del 2000% en las operaciones basadas en diccionarios.

¿Cuál es su experiencia al respecto? ¿En qué tipo de tarea cada uno es un claro ganador?

Doppelganger
fuente
6
En realidad, esto no es una encuesta, no hay opciones predefinidas, necesito una idea de qué herramienta hace qué tipo de trabajo mejor.
Doppelganger

Respuestas:

94

Flujo típico de mainframe ...

Input Disk/Tape/User (runtime) --> Job Control Language (JCL) --> Output Disk/Tape/Screen/Printer
                                   |                          ^
                                   v                          |
                                   `--> COBOL Program --------' 

Flujo típico de Linux ...

Input Disk/SSD/User (runtime) --> sh/bash/ksh/zsh/... ----------> Output Disk/SSD/Screen/Printer
                                   |                          ^
                                   v                          |
                                   `--> Python script --------'
                                   |                          ^
                                   v                          |
                                   `--> awk script -----------'
                                   |                          ^
                                   v                          |
                                   `--> sed script -----------'
                                   |                          ^
                                   v                          |
                                   `--> C/C++ program --------'
                                   |                          ^
                                   v                          |
                                   `--- Java program ---------'
                                   |                          ^
                                   v                          |
                                   :                          :

Las cáscaras son el pegamento de Linux

Los shells de Linux como sh / ksh / bash / ... proporcionan facilidades de designación de entrada / salida / control de flujo muy parecidas al antiguo lenguaje de control de trabajos de mainframe ... ¡pero con esteroides! Son lenguajes completos de Turing por derecho propio mientras se optimizan para pasar datos y control de manera eficiente hacia y desde otros procesos de ejecución escritos en cualquier idioma que admita el sistema operativo.

La mayoría de las aplicaciones de Linux, independientemente del idioma en el que esté escrito la mayor parte del programa, dependen de scripts de shell y Bash se ha convertido en el más común. Al hacer clic en un icono en el escritorio, normalmente se ejecuta un breve script Bash . Ese script, ya sea directa o indirectamente, sabe dónde están todos los archivos necesarios y establece variables y parámetros de línea de comando, finalmente llamando al programa. Ese es el uso más simple de un caparazón.

Sin embargo, Linux tal como lo conocemos difícilmente sería Linux sin los miles de scripts de shell que inician el sistema, responden a eventos, controlan las prioridades de ejecución y compilan, configuran y ejecutan programas. Muchos de ellos son bastante grandes y complejos.

Los shells proporcionan una infraestructura que nos permite usar componentes prediseñados que están vinculados entre sí en tiempo de ejecución en lugar de compilar. Esos componentes son programas independientes por derecho propio que se pueden usar solos o en otras combinaciones sin volver a compilar. La sintaxis para llamarlos es indistinguible de la de un comando incorporado de Bash y, de hecho, existen numerosos comandos incorporados para los que también hay un ejecutable independiente en el sistema, que a menudo tiene opciones adicionales.

No existe una diferencia de rendimiento en todo el lenguaje entre Python y Bash . Depende completamente de cómo esté codificado cada uno y de qué herramientas externas se llamen.

Cualquiera de las herramientas conocidas como awk, sed, grep, bc, dc, tr, etc. dejará de hacer esas operaciones en cualquier idioma en el polvo. Bash se prefiere para cualquier cosa sin una interfaz gráfica de usuario, ya que es más fácil y más eficiente llamar y devolver datos desde una herramienta como las que tienen Bash que Python .

Actuación

Depende de a qué programas llame el script de shell Bash y de su idoneidad para la subtarea que se les asigne, si el rendimiento general y / o la capacidad de respuesta será mejor o peor que el Python equivalente . Para complicar las cosas , Python , como la mayoría de los lenguajes, también puede llamar a otros ejecutables, aunque es más engorroso y, por lo tanto, no se usa con tanta frecuencia.

Interfaz de usuario

Un área donde Python es el claro ganador es la interfaz de usuario. Eso lo convierte en un lenguaje excelente para crear aplicaciones locales o cliente-servidor, ya que admite de forma nativa gráficos GTK y es mucho más intuitivo que Bash .

Bash solo entiende texto. Se deben llamar a otras herramientas para una GUI y los datos devueltos desde ellas. Una secuencia de comandos de Python es una opción. Las opciones más rápidas pero menos flexibles son los binarios como YAD, Zenity y GTKDialog .

Mientras que los shells como Bash funcionan bien con GUI como Yad , GtkDialog (interfaz tipo XML incrustado para funciones GTK +) , dialog y xmessage , Python es mucho más capaz y, por lo tanto, mejor para ventanas GUI complejas.

Resumen

Construir con scripts de shell es como armar una computadora con componentes listos para usar como lo son las PC de escritorio.

Construir con Python , C ++ o casi cualquier otro lenguaje es más como construir una computadora soldando los chips (bibliotecas) y otras partes electrónicas juntas como lo hacen los teléfonos inteligentes.

Los mejores resultados generalmente se obtienen al usar una combinación de idiomas donde cada uno puede hacer lo que mejor sabe hacer. Un desarrollador llama a esto " programación políglota ".

DocSalvager
fuente
16
No reconozco cómo se puede aceptar la respuesta. No proporciona información sobre para qué tareas son más adecuados esos dos.
vigilancer
2
@vigilancer Espero que las modificaciones y adiciones que se acaban de publicar sean útiles.
DocSalvager
1
Si bien estoy de acuerdo con otros comentarios, esto no responde exactamente a la pregunta. ¡Esta es una de las mejores respuestas que he leído!
Jim Mitchener
72

Generalmente, bash funciona mejor que python solo en aquellos entornos donde python no está disponible. :)

En serio, tengo que lidiar con ambos idiomas a diario, y tomaré Python instantáneamente sobre bash si tengo la opción. Por desgracia, me veo obligado a usar bash en ciertas plataformas "pequeñas" porque alguien ha decidido (erróneamente, en mi humilde opinión) que Python es "demasiado grande" para caber.

Si bien es cierto que bash puede ser más rápido que python para algunas tareas seleccionadas, nunca puede ser tan rápido de desarrollar ni tan fácil de mantener (al menos después de pasar las 10 líneas de código más o menos). El único punto fuerte de Bash con pitón, rubí o lua, etc., es su ubicuidad.

Kevin pequeño
fuente
4
¿No está Python ya en todos los Linux / Unix, incluso en MacOS? Tengo curiosidad por saber qué operaciones son más rápidas en bash; por lo que entendí, llamar a diferentes comandos separados lo hace mucho más lento que los comandos de Python oso del shutilmódulo.
NoBugs
1
@NoBugs Definitivamente no estaría en todas las distribuciones de Linux / Unix. Es casi seguro que viene en todas las distribuciones principales de Linux (por ejemplo, distribuciones basadas en Debian, slackware, etc.) y Mac OS X, sin embargo, si construye su propia iso con yocto ( yoctoproject.org ), entonces no podría tenerla, ya que usted mismo personaliza cada paquete. Pero probablemente sea seguro decir que para cualquier sistema operativo Unix importante hoy en día, vendrá instalado con python2 (al menos) y quizás también con python3.
dylnmc
Python es un excelente lenguaje de secuencias de comandos para tareas complejas, como una GUI con todas las funciones. Igualmente importante, hace cumplir las buenas prácticas de programación para que los programas sean más fáciles de mantener. Bash requiere la imposición de buenas prácticas aprendidas en otros lugares para ser mantenible. Al hacerlo, y al usar una utilidad de diálogo GUI o Python para UI, brinda un rendimiento superior (a través de programas de utilidad extremadamente rápidos llamados desde Bash), así como una buena UX.
DocSalvager
34

La eficiencia del desarrollador me importa mucho más en escenarios donde tanto bash como Python son opciones sensatas.

Algunas tareas se prestan bien a bash y otras a Python. Tampoco es inusual para mí comenzar algo como un script bash y cambiarlo a Python a medida que evoluciona durante varias semanas.

Una gran ventaja que tiene Python es en casos de esquina en torno al manejo de nombres de archivos, mientras que tiene glob , shutil , subproceso y otros para necesidades comunes de scripting.

Roger Pate
fuente
5
La pregunta apuntaba a una comparación "basada en el rendimiento" que implica el rendimiento de la máquina y no el rendimiento del desarrollador. Vea mis pruebas de rendimiento en otra respuesta.
Grzegorz Luczywo
25

Al escribir guiones, el rendimiento no importa (en la mayoría de los casos).
Si le importa el rendimiento, 'Python vs Bash' es una pregunta falsa.

Python :
+ más fácil de escribir
+ más fácil de mantener
+ reutilización de código más fácil (intenta encontrar una forma universal a prueba de errores para incluir archivos con código común sh, te reto)
+ ¡también puedes hacer OOP con él!
+ análisis de argumentos más fácil. bueno, no más fácil, exactamente. todavía será demasiado prolijo para mi gusto, pero Python tiene una función argparseincorporada.
- 'subproceso' feo y feo. Intenta encadenar comandos y no llorar por lo feo que se volverá tu código. especialmente si le preocupan los códigos de salida.

Bash :
+ ubicuidad, como se dijo antes, de hecho.
+ Encadenamiento de comandos simples. así es como unes diferentes comandos de una manera simple. Además Bash(no sh) tiene algunas mejoras, como pipefail, por lo que el encadenamiento es realmente corto y expresivo.
+ no requieren la instalación de programas de terceros. se puede ejecutar de inmediato.
- Dios, está lleno de trampas. IFS, CDPATH ... miles de ellos.

Si uno escribe un script de más de 100 LOC: elija Python
Si necesita manipulación de ruta en el script: elija Python (3)
Si necesita algo parecido aliaspero un poco complicado: elija Bash / sh

De todos modos, uno debería probar ambos lados para hacerse una idea de lo que son capaces de hacer.

Tal vez la respuesta pueda extenderse con paquetes y puntos de soporte IDE, pero no estoy familiarizado con estos lados.

Como siempre, tienes que elegir entre sándwich de turd y ducha gigante. Y recuerde, hace solo unos años Perl era una nueva esperanza. Dónde está ahora.

vigilante
fuente
4
Sí, un código con bash vive para siempre. Codifiqué mucho Perl, ahora son inútiles.
Raymond gsh
Solo en perspectiva ... El script actual más grande que he escrito, que uso todo el día todos los días, pesa 4121 líneas de código bash real, sin comentarios o en blanco. Con los comentarios extensos y demás, hace 7261 líneas. Viene acompañado de un archivo de ayuda de documentos tipo página de manual para cada función que son otras 6650 líneas. Cada función tiene una opción que puede recuperar y mostrar instantáneamente su texto de ayuda en la mejor forma de salida disponible que actualmente incluye 3 versiones de YAD, Zenity, dialog o simplemente texto CLI sin formato. Yo lo llamo 'kit'. está en la versión 44 al momento de escribir este artículo.
DocSalvager
¡Esto es pesado! (c)
vigilancer
1
No creo que LoC sea realmente el factor de decisión para elegir Python. Más, ¿qué tan compleja es la tarea que estás haciendo? Si solo está encadenando 100 comandos, probablemente esté bien, si solo tiene 30 LoC en bash pero podría ser más fácil de entender en Python: use python.
JFord
@Akito está bien, cuando nada lo toca. pero hay algunas situaciones en las que las cosas podrían salir mal. lo configuró como no predeterminado y olvidó borrarlo. algo externo lo cambió, pero su secuencia de comandos se basa en el valor predeterminado, y así sucesivamente. siempre hay que tener en cuenta a IFS, porque algunas herramientas lo usan implícitamente.
vigilancer
22

Bash en términos de rendimiento supera a Python en el tiempo de inicio del proceso.

Aquí hay algunas medidas de mi computadora portátil core i7 con Linux Mint:

Starting process                       Startup time

empty /bin/sh script                   1.7 ms
empty /bin/bash script                 2.8 ms
empty python script                    11.1 ms
python script with a few libs*         110 ms

* Las librerías cargadas en Python son: os, os.path, json, time, request, threading, subprocess

Esto muestra una gran diferencia, sin embargo, el tiempo de ejecución de bash se degrada rápidamente si tiene que hacer algo sensato, ya que generalmente debe llamar a procesos externos.

Si te importa el rendimiento, usa bash solo para:

  • scripts realmente simples y frecuentemente llamados
  • scripts que llaman principalmente a otros procesos
  • cuando necesite una fricción mínima entre las acciones administrativas manuales y las secuencias de comandos, verifique rápidamente algunos comandos y colóquelos en el archivo .sh
Grzegorz Luczywo
fuente
... y /bin/echosupera a bash en tal magnitud, es difícil de medir. Entonces, en lugar de ejecutar bash, puede usar /bin/echo mycommand > named_pipe(enviar comandos / mensajes a una tubería o conector con nombre) ... y tener un proceso de Python en segundo plano que lea los comandos / instrucciones de esa tubería y los ejecute. Entonces, bash no es realmente una buena "optimización de costos de inicio".
Cezary Baginski
Por lo general, se supone que debe usar subprocesos en lugar de procesos cuando la tarea es realmente corta y rápida. Múltiples procesos son algo de alto nivel y siempre que el inicio de uno sea en medio segundo, eso parece bastante razonable en su mayor parte, ¿no crees?
Timothy Swan
16

Bash es principalmente un lenguaje de secuencias de comandos por lotes / shell con mucho menos soporte para varios tipos de datos y todo tipo de peculiaridades en torno a las estructuras de control, sin mencionar los problemas de compatibilidad.

¿Cual es mas rápido? Tampoco, porque aquí no está comparando manzanas con manzanas. Si tuvieras que ordenar un archivo de texto ascii y estabas usando herramientas como zcat, sort, uniq y sed, entonces fumarás en Python.

Sin embargo, si necesita un entorno de programación adecuado que admita el punto flotante y varios flujos de control, Python gana sin lugar a dudas. Si escribió un algoritmo recursivo en Bash y Python, la versión de Python ganará en un orden de magnitud o más.

Justin
fuente
13
Entonces, la moraleja de mi perorata es: use la herramienta adecuada para el trabajo correcto.
Justin
2
el punto flotante es compatible con herramientas como awk, bc y con shells como zsh / ksh, entonces, ¿por qué dices que Python gana sin lugar a dudas?
ghostdog74
4
Porque esas herramientas no son Bash. Estaba señalando una clara diferencia. Esas herramientas se utilizan en un script de shell, pero el propio Bash nativo no admite el punto flotante.
Justin
2
No. Pruébelo usted mismo. gzip un archivo de registro grande y use zcat, sort, etc. para hacer algunos filtros y luego use las bibliotecas nativas de Python. Es significativamente más rápido con las herramientas nativas.
Justin
6
@justin, sí, estas herramientas no son Bash, pero han existido desde la antigüedad y se utilizan a menudo en secuencias de comandos de shell. si quieres un punto flotante, usa awk / bc. Es una combinación de estas herramientas que hacen que los scripts de shell sean tan poderosos como Python.
ghostdog74
12

Si está buscando improvisar una utilidad rápida con un mínimo esfuerzo, bash es bueno. Para envolver una aplicación, bash es invaluable.

Cualquier cosa que pueda hacer que regrese una y otra vez para agregar mejoras probablemente (aunque no siempre) se adapte mejor a un lenguaje como Python, ya que el código Bash que comprende más de 1000 líneas se vuelve muy difícil de mantener. El código bash también es irritante para depurar cuando se hace largo .......

Parte del problema con este tipo de preguntas es, según mi experiencia, que los scripts de shell suelen ser tareas personalizadas. Ha habido muy pocas tareas de scripting de shell con las que me he encontrado donde ya existe una solución disponible gratuitamente.

zamhassam
fuente
8

Hay 2 escenarios en los que el rendimiento de Bash es al menos igual, creo:

  • Scripting de utilidades de línea de comando
  • Secuencias de comandos que tardan poco en ejecutarse; donde iniciar el intérprete de Python lleva más tiempo que la operación en sí

Dicho esto, normalmente no me preocupo por el rendimiento del lenguaje de scripting en sí. Si el rendimiento es un problema real, no escribe un script sino que programa (posiblemente en Python).

extraneón
fuente
4

Estoy publicando esta respuesta tardía principalmente porque a Google le gusta esta pregunta.

Creo que el problema y el contexto realmente deberían ser sobre el flujo de trabajo, no sobre las herramientas. La filosofía general es siempre "Utilice la herramienta adecuada para el trabajo". Pero antes de esto viene uno que muchos olvidan cuando se pierden en las herramientas: "Haz el trabajo".

Cuando tengo un problema que no está completamente definido, casi siempre comienzo con Bash. He resuelto algunos problemas complicados en grandes scripts de Bash que son legibles y fáciles de mantener.

Pero, ¿cuándo comienza el problema a exceder lo que se le debería pedir a Bash? Tengo algunos cheques que utilizo para darme advertencias:

  1. ¿Estoy deseando que Bash tuviera matrices 2D (o superiores)? Si es así, es hora de darse cuenta de que Bash no es un gran lenguaje de procesamiento de datos.
  2. ¿Estoy haciendo más trabajo preparando datos para otras utilidades de lo que realmente estoy ejecutando esas utilidades? Si es así, es hora de darse cuenta de que Bash no es un gran lenguaje de procesamiento de datos.
  3. ¿Mi script simplemente se está volviendo demasiado grande para administrarlo? En caso afirmativo, es importante darse cuenta de que si bien Bash puede importar bibliotecas de scripts, carece de un sistema de paquetes como otros lenguajes. Es realmente un lenguaje de "rodar tu propio" en comparación con la mayoría de los demás. Por otra parte, tiene una enorme cantidad de funcionalidad incorporada (algunos dicen demasiado ...)

La lista continua. En resumidas cuentas, cuando trabajas más duro para mantener tus scripts en ejecución que agregas funciones, es hora de dejar Bash.

Supongamos que ha decidido trasladar su trabajo a Python. Si sus scripts Bash están limpios, la conversión inicial es bastante sencilla. Incluso hay varios convertidores / traductores que harán el primer paso por usted.

La siguiente pregunta es: ¿A qué renuncias al cambiarte a Python?

  1. Todas las llamadas a utilidades externas deben estar envueltas en algo del subprocessmódulo (o equivalente). Hay varias formas de hacer esto, y hasta 3.7 tomó un poco de esfuerzo hacerlo bien (3.7 mejorado subprocess.run()para manejar todos los casos comunes por sí solo).

  2. Sorprendentemente, Python no tiene una utilidad de no bloqueo independiente de la plataforma estándar (con tiempo de espera) para sondear el teclado (stdin). El readcomando Bash es una herramienta increíble para la interacción simple del usuario. Mi uso más común es mostrar una ruleta hasta que el usuario presione una tecla, mientras que también ejecuta una función de sondeo (con cada paso de la ruleta) para asegurarme de que todo sigue funcionando bien. Este es un problema más difícil de lo que parece al principio, por lo que a menudo simplemente hago una llamada a Bash: Caro, pero hace precisamente lo que necesito.

  3. Si está desarrollando en un sistema integrado o con restricciones de memoria, la huella de memoria de Python puede ser muchas veces mayor que la de Bash (dependiendo de la tarea en cuestión). Además, casi siempre hay una instancia de Bash en la memoria, lo que puede no ser el caso de Python.

  4. Para los scripts que se ejecutan una vez y salen rápidamente, el tiempo de inicio de Python puede ser mucho más largo que el de Bash. Pero si la secuencia de comandos contiene cálculos importantes, Python avanza rápidamente.

  5. Python tiene el sistema de paquetes más completo del planeta. Cuando Bash se vuelve incluso un poco complejo, Python probablemente tiene un paquete que hace que partes enteras de Bash se conviertan en una sola llamada. Sin embargo, encontrar los paquetes adecuados para usar es la parte más grande y desalentadora de convertirse en un Pythonista. Afortunadamente, Google y StackExchange son tus amigos.

BobC
fuente
2

No sé si esto es exacto, pero he descubierto que python / ruby ​​funciona mucho mejor para scripts que tienen muchos cálculos matemáticos. De lo contrario, debe utilizar dco alguna otra "calculadora de precisión arbitraria". Simplemente se convierte en un gran dolor. Con Python tienes mucho más control sobre los flotadores que los ints y es mucho más fácil realizar muchos cálculos y, a veces.

En particular, nunca trabajaría con un script bash para manejar información binaria o bytes. En su lugar, usaría algo como python (tal vez) o C ++ o incluso Node.JS.

dylnmc
fuente
La aritmética de bash es estrictamente entera, por lo que debe realizar operaciones de punto flotante llamando a otra cosa (como awk o dc) y capturando la salida de ella. Las cosas monetarias simples a menudo se pueden hacer internamente simplemente multiplicando por 100 y ajustando el punto decimal en la salida.
DocSalvager
0

En cuanto al rendimiento, ambos pueden hacer lo mismo por igual, por lo que la pregunta es ¿cuál ahorra más tiempo de desarrollo?

Bash se basa en llamar a otros comandos y canalizarlos para crear otros nuevos. Esto tiene la ventaja de que puede crear rápidamente nuevos programas solo con el código prestado de otras personas, sin importar el lenguaje de programación que utilicen.

Esto también tiene el efecto secundario de resistir bastante bien los cambios en los subcomandos, ya que la interfaz entre ellos es solo texto sin formato.

Además, Bash es muy permisivo sobre cómo escribir en él. Esto significa que funcionará bien para una variedad más amplia de contextos, pero también depende de que el programador tenga la intención de codificar de una manera limpia y segura. De lo contrario, Bash no te impedirá crear un desastre.

Python está más estructurado en estilo, por lo que un programador desordenado no será tan desordenado. También funcionará en sistemas operativos fuera de Linux, lo que lo hace instantáneamente más apropiado si necesita ese tipo de portabilidad.

Pero no es tan simple para llamar a otros comandos. Entonces, si su sistema operativo es Unix, lo más probable es que encuentre que desarrollar en Bash es la forma más rápida de hacerlo.

Cuándo usar Bash:

  • Es un programa no gráfico, o el motor de uno gráfico.
  • Es solo para Unix.

Cuándo usar Python:

  • Es un programa gráfico.
  • Funcionará en Windows.
Alberto Salvia Novella
fuente