Estoy evaluando la expresión 6^6^6usando pythony por bcseparado.
El contenido del archivo python es print 6**6**6. Cuando ejecuto time python test.py, obtengo la salida como
real 0m0.067s
user 0m0.050s
sys 0m0.011s
Y luego, ejecuté el comando time echo 6^6^6 | bcque me dio el siguiente resultado
real 0m0.205s
user 0m0.197s
sys 0m0.005s
A partir de estos resultados, está claro que el tiempo del sistema tomado por python y bc fue de 11 ms y 5 ms respectivamente. El comando bc superó a Python en el nivel de tiempo del sistema, pero en lo que respecta al usuario y a Python en tiempo real fue casi 4 veces más rápido que bc . Lo que pudo haber ido allí. No he dado ninguna prioridad a los procesos como tal. Estoy tratando de entender esta situación.
python
performance
process-management
bc
ganessh
fuente
fuente

echo | bcimplica el lanzamiento de una subshell debido a la canalización, de ahí es probable que provenga parte de su tiempo de usuario adicional. Para hacer de esto una prueba equitativa, el script de Python debe leer de stdin para que puedatime echo 6**6**6 | whatever.py.echo 6^6^6 | time bc.6**6**6expresión se calcula en tiempo de compilación . Sin embargo, dado que está iniciando el archivo directamente en lugar de importarlo desde un módulo, esto no debería importar. Para ver la diferencia puesta10**12345678en una.pyarchivo e intentar importarlo desde el intérprete interactivo. Luego cierre el intérprete, reinícielo e importeanuevamente. La primera vez debería llevar una cantidad de tiempo notable (porque Python está compilando el módulo), mientras que la segunda vez carga el.pyc, que debería ser instantáneo,Respuestas:
Python importa una gran cantidad de archivos al inicio:
Cada uno de estos requiere un número aún mayor de intentos de abrir un archivo Python, porque hay muchas formas de definir un módulo:
Cada "intento", excepto los que están integrados, requiere un nivel de sistema operativo / llamadas al sistema, y cada "importación" parece desencadenar alrededor de 8 mensajes de "intento". (Hubo formas de reducir esto usando zipimport, y cada ruta en su PYTHONPATH puede requerir otra llamada).
Esto significa que hay casi 200 llamadas al sistema de estadísticas antes de que Python se inicie en mi máquina, y "time" asigna eso a "sys" en lugar de "usuario", porque el programa de usuario está esperando que el sistema haga las cosas.
En comparación, y como dijo terdon, "bc" no tiene ese alto costo inicial. Al observar la salida de dtruss (tengo una Mac; "strace" para un sistema operativo basado en Linux), veo que bc no hace ninguna llamada al sistema open () o stat (), excepto para cargar algunas compartidas las bibliotecas son el comienzo, que por supuesto Python también lo hace. Además, Python tiene más archivos para leer, antes de que esté listo para procesar cualquier cosa.
Esperar el disco es lento.
Puede tener una idea del costo de inicio de Python haciendo:
Son 0.032s en mi máquina, mientras que 'print 6 ** 6 ** 6' es 0.072s, por lo que el costo de inicio es 1 / 2rd del tiempo total y el cálculo + conversión a decimal es la otra mitad. Mientras:
toma 0.005s, y "6 ^ 6 ^ 6" toma 0.184s por lo que la exponenciación de bc es 4 veces más lenta que la de Python a pesar de que es 7 veces más rápido para comenzar.
fuente
Encontré una buena respuesta en SO que explica los diferentes campos:
Entonces, en su ejemplo específico, la versión de Python es más rápida en términos del tiempo real que lleva completar. Sin embargo, el enfoque de Python pasa más tiempo en el espacio del núcleo, haciendo llamadas a las funciones del núcleo. El
bccomando no pasa esencialmente tiempo en el espacio del kernel y todo su tiempo se gasta en el espacio del usuario, presumiblemente ejecutandobccódigo interno .Esto no hace ninguna diferencia para usted, la única información que realmente le importa es
realcuál es el tiempo real transcurrido entre el lanzamiento del comando y la obtención de su salida.También debe tener en cuenta que estas pequeñas diferencias no son estables, también dependerán de la carga de su sistema y cambiarán cada vez que ejecute el comando:
fuente
Lo explicaré desde otra perspectiva.
Para ser justos,
bctiene ventaja ya que no tiene que leer nada del disco y solo necesita sus blob / binarios, mientras que python tiene que importar una serie de módulos + leer un archivo. Entonces su prueba puede estar sesgada haciabc. Para probarlo realmente debes usarbc -q filewherefilecontiene:Cambiar solo eso modificó el tiempo de uso
echo:Para usar el archivo:
(deberá usar el método de terdon para notar mayores diferencias, pero al menos sabemos que lo son)
Ahora, desde la perspectiva de Python, Python necesita leer desde el disco, compilar y ejecutar cada vez que el archivo, además de cargar módulos como señala Andrew , lo que hace que el tiempo de ejecución sea más lento. Si compila el código de bytes del script de Python, notará que se necesita un 50% menos de tiempo total para ejecutar el código:
compilado:
Como puede ver, hay varios factores que pueden afectar la ejecución del tiempo entre diferentes herramientas.
fuente
He tenido el beneficio de leer las otras respuestas. Para empezar la gente como yo deben saber la razón por la que estamos tratando con un enorme número entero tal aquí es que tanto
Pythonybchacer asociativo por la derecha expansión exponencial, lo que significa que este no es6^36que estamos evaluando, sino6^46656que es considerablemente más grande. 1Usando variaciones en los siguientes comandos, podemos extraer un promedio para un elemento específico de la salida de la
timepalabra reservada y el comando:Es posible ir a otra ruta y eliminar el archivo por completo de la comparación. Además, podemos comparar el tiempo de bc con algo como el
dccomando, ya que históricamente el primero es un "procesador frontal" para el segundo. Los siguientes comandos fueron cronometrados:Tenga en cuenta que el
dccomando es asociativo a la izquierda para exponenciación. 2Tenemos algunos resultados con
time(bash) para 1000 iteraciones (en segundos):bcydcofrecer un rendimiento comparable en este contexto.Resultados menos precisos 3,
/usr/bin/timees decir,timecomando GNU (la precisión de la escala no es válida aquí pero los resultados son similares):Una ventaja de esto
/usr/bin/timees que ofrece la-vopción que produce mucha más información que podría ser útil eventualmente.También es posible evaluar esto internamente, por así decirlo con el
timeitmódulo Python:Eso es un poco más rápido de lo que vimos antes. Probemos con el propio intérprete:
Eso es lo más rápido que he visto.
Si evaluamos una exponenciación menor
6^6, entonces el comando de tiempo arroja resultados sorprendentes: usando los mismosforcomandos de bucle que usamos ahora tenemos:Entonces, ¿con un número entero más pequeño
bces de repente mucho más rápido? Desde el reinicio del sistema hasta la segunda ejecución no hay diferencia. Sin embargo, al mismo tiempo, si usamostimeitpara Python, obtenemos:Esto es microsegundos , no milisegundos, por lo que esto no coincide con los resultados mucho más lentos utilizando el
forbucle. Tal vez se requieran otras herramientas para probar esto más y, como otros han explicado, hay más de lo que parece a simple vista. Parece que Python fue más rápido en el escenario de la pregunta, pero no está claro si se pueden sacar conclusiones más allá de eso ...1. No hace falta decir que está más allá del alcance de algo como la expansión aritmética del eco, es decir
echo $((6**6**6)),bashtambién resulta ser una asociación correcta para eso6^6^6 = 6^(6^6).2. Comparar con esto:
6 6 ^ 6 ^ p.3. Es posible que el comando de tiempo de GNU proporcione más información cuando se ejecuta en BSD UNIX (documento de información de tiempo de GNU): la mayor parte de la información mostrada por 'tiempo' se deriva de la llamada al sistema 'wait3'. Los números son tan buenos como los devueltos por 'wait3'. Muchos sistemas no miden todos los recursos sobre los que puede informar el "tiempo"; esos recursos se informan como cero. Los sistemas que miden la mayoría o la totalidad de los recursos se basan en 4.2 o 4.3BSD. Las versiones posteriores de BSD utilizan un código de administración de memoria diferente que mide menos recursos. - En los sistemas que no tienen una llamada 'wait3' que devuelve información de estado, en su lugar se usa la llamada del sistema 'times'. Proporciona mucha menos información que 'wait3', por lo que en esos sistemas el 'tiempo' informa que la mayoría de los recursos son cero.
fuente