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 Python
y bc
hacer asociativo por la derecha expansión exponencial, lo que significa que este no es 6^36
que estamos evaluando, sino 6^46656
que es considerablemente más grande. 1
Usando variaciones en los siguientes comandos, podemos extraer un promedio para un elemento específico de la salida de la time
palabra reservada y el comando:
for i in {1..1000}; do (time echo 6^6^6 | bc > /dev/null) 2>&1; done | grep 'rea' | sed -e s/.*m// | awk '{sum += $1} END {print sum / NR}'
for i in {1..1000}; do (/usr/bin/time -v sh -c 'echo 6^6^6 | bc > /dev/null') 2>&1; done | grep 'Use' | sed -e s/.*:// | awk '{sum += $1} END {print sum / NR}'
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 dc
comando, ya que históricamente el primero es un "procesador frontal" para el segundo. Los siguientes comandos fueron cronometrados:
echo 6^6^6 | bc
echo 6 6 6 ^ ^ p | dc
echo print 6**6**6 | python2.7
Tenga en cuenta que el dc
comando es asociativo a la izquierda para exponenciación. 2
Tenemos algunos resultados con time
(bash) para 1000 iteraciones (en segundos):
0.229678 real bc
0.228348 user bc
0.000569 sys bc
0.23306 real dc
0.231786 user dc
0.000395 sys dc
0.07 real python
0.065907 user python
0.003141 sys python
bc
y dc
ofrecer un rendimiento comparable en este contexto.
Resultados menos precisos 3,/usr/bin/time
es decir, time
comando GNU (la precisión de la escala no es válida aquí pero los resultados son similares):
0.2224 user bc
0 sys bc
0.23 Elapsed bc
0.22998 user dc
0 sys dc
0.23 Elapsed dc
0.06008 user python
0 sys python
0.07 Elapsed python
Una ventaja de esto /usr/bin/time
es que ofrece la -v
opció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 timeit
módulo Python:
python2.7 -m timeit -n 1000 -r 1 'print 6**6**6' | grep 'loops'
1000 loops, best of 1: 55.4 msec per loop
Eso es un poco más rápido de lo que vimos antes. Probemos con el propio intérprete:
>>> import timeit
>>> import sys
>>> import os
>>> T = timeit.Timer("print 6**6**6")
>>> n = int(1000)
>>> f = open(os.devnull, 'w')
>>> sys.stdout = f
>>> t = t.timeit(n)
>>> sys.stdout = sys.__stdout__
>>> print t/n
0.0553743481636
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 mismos for
comandos de bucle que usamos ahora tenemos:
0.001001 bc real
0.000304 user
0.000554 sys
0.014 python real i.e. 10x more than bc??
0.010432 user
0.002606 sys
Entonces, ¿con un número entero más pequeño bc
es 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 usamos timeit
para Python, obtenemos:
python2.7 -m timeit -n 100000 -r 1 'print 6**6' | grep loops
100000 loops, best of 1: 0.468 usec per loop
Esto es microsegundos , no milisegundos, por lo que esto no coincide con los resultados mucho más lentos utilizando el for
bucle. 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))
, bash
también resulta ser una asociación correcta para eso 6^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.