medir - ¿Cómo obtengo el tiempo de ejecución de un programa Python?
tiempo de ejecucion python (24)
Tengo un programa de línea de comandos en Python que tarda un poco en terminar. Quiero saber el tiempo exacto que lleva terminar de correr.
He mirado el módulo timeit
, pero parece que es solo para pequeños fragmentos de código. Quiero cronometrar todo el programa.
He mirado el módulo timeit, pero parece que es solo para pequeños fragmentos de código. Quiero cronometrar todo el programa.
$ python -mtimeit -n1 -r1 -t -s "from your_module import main" "main()"
Ejecuta la función your_module.main()
una vez e imprime el tiempo transcurrido usando la función time.time()
como un temporizador.
Para emular /usr/bin/time
en Python, vea el subproceso de Python con / usr / bin / time: ¿cómo capturar información de tiempo pero ignorar todas las demás salidas? .
Para medir el tiempo de CPU (por ejemplo, no incluir el tiempo durante time.sleep()
) para cada función, puede usar el módulo de profile
( cProfile
en Python 2):
$ python3 -mprofile your_module.py
Puede pasar el comando -p
a timeit
anterior si desea usar el mismo temporizador que utiliza el módulo de profile
.
Consulte ¿Cómo puede crear un perfil de un script de Python?
Para la gente de datos que usan Jupyter Notebooks
En una celda, puede usar el comando %%time
magic de Jupyter para medir el tiempo de ejecución:
%%time
[ x**2 for x in range(10000)]
Salida
Tiempos de CPU: usuario 4.54 ms, sys: 0 ns, total: 4.54 ms
Tiempo de pared: 4.12 ms
Esto solo capturará el tiempo de ejecución de una celda en particular. Si desea capturar el tiempo de ejecución de todo el cuaderno (es decir, el programa), puede crear un nuevo cuaderno en el mismo directorio y en el nuevo cuaderno ejecutar todas las celdas:
Supongamos que el cuaderno anterior se llama example_notebook.ipynb
. En un nuevo cuaderno dentro del mismo directorio:
# Convert your notebook to a .py script:
!jupyter nbconvert --to script example_notebook.ipynb
# Run the example_notebook with -t flag for time
%run -t example_notebook
Salida
Tiempos de CPU IPython (estimados): Usuario: 0,00 s.
Sistema: 0.00 s.
Tiempo de pared: 0.00 s.
Aún mejor para Linux: /usr/bin/time
$ /usr/bin/time -v python rhtest2.py
Command being timed: "python rhtest2.py"
User time (seconds): 4.13
System time (seconds): 0.07
Percent of CPU this job got: 91%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:04.58
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 0
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 15
Minor (reclaiming a frame) page faults: 5095
Voluntary context switches: 27
Involuntary context switches: 279
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
Normalmente, solo el time
es una estructura de shell más simple que oculta la capacidad /usr/bin/time
.
El siguiente fragmento imprime el tiempo transcurrido en un formato agradable <HH:MM:SS>
legible por humanos.
import time
from datetime import timedelta
start_time = time.time()
#
# Perform lots of computations.
#
elapsed_time_secs = time.time() - start_time
msg = "Execution took: %s secs (Wall clock time)" % timedelta(seconds=round(elapsed_time_secs))
print(msg)
El tiempo de la medida de ejecución de un programa Python podría ser inconsistente dependiendo de:
- El mismo programa puede ser evaluado usando diferentes algoritmos.
- El tiempo de ejecución varía entre algoritmos
- El tiempo de ejecución varía entre las implementaciones
- El tiempo de ejecución varía entre las computadoras
- El tiempo de ejecución no es predecible basado en pequeñas entradas
Esto se debe a que la forma más efectiva es usar la "Orden de Crecimiento" y aprender la notación de la "O" grande para hacerlo correctamente, https://en.wikipedia.org/wiki/Big_O_notation
De todos modos, puede intentar evaluar el rendimiento de cualquier programa Python en pasos de conteo por máquina específicos por segundo utilizando este algoritmo simple: adáptelo al programa que desea evaluar.
import time
now = time.time()
future = now + 10
step = 4 # why 4 steps? because until here already 4 operations executed
while time.time() < future:
step += 3 # why 3 again? because while loop execute 1 comparison and 1 plus equal statement
step += 4 # why 3 more? because 1 comparison starting while when time is over plus final assignment of step + 1 and print statement
print(str(int(step / 10)) + " steps per second")
Espero que esto te ayude.
Esta es la respuesta de Paul McGuire que funciona para mí. Sólo en caso de que alguien estuviera teniendo problemas para ejecutar esa.
import atexit
from time import clock
def reduce(function, iterable, initializer=None):
it = iter(iterable)
if initializer is None:
value = next(it)
else:
value = initializer
for element in it:
value = function(value, element)
return value
def secondsToStr(t):
return "%d:%02d:%02d.%03d" % /
reduce(lambda ll,b : divmod(ll[0],b) + ll[1:],
[(t*1000,),1000,60,60])
line = "="*40
def log(s, elapsed=None):
print (line)
print (secondsToStr(clock()), ''-'', s)
if elapsed:
print ("Elapsed time:", elapsed)
print (line)
def endlog():
end = clock()
elapsed = end-start
log("End Program", secondsToStr(elapsed))
def now():
return secondsToStr(clock())
def main():
start = clock()
atexit.register(endlog)
log("Start Program")
llame a timing.main()
desde su programa después de importar el archivo.
Hay un módulo timeit
que se puede usar para timeit
los tiempos de ejecución de los códigos python. Tiene documentación detallada y ejemplos en documentos de Python ( https://docs.python.org/2/library/timeit.html )
Ipython "timeit" cualquier script:
def foo():
%run bar.py
timeit foo()
La forma más sencilla en Python:
import time
start_time = time.time()
main()
print("--- %s seconds ---" % (time.time() - start_time))
Esto supone que su programa tarda al menos una décima de segundo en ejecutarse.
Huellas dactilares:
--- 0.764891862869 seconds ---
La solución de rogeriopvl funciona bien, pero si desea información más específica, puede usar el generador de perfiles incorporado de python. Revisa esta página:
http://docs.python.org/library/profile.html
un generador de perfiles le brinda mucha información útil, como el tiempo empleado en cada función
Me gusta la salida que proporciona el módulo datetime
, donde los objetos delta del tiempo muestran días, horas, minutos, etc., según sea necesario, de una manera legible para el ser humano.
Por ejemplo:
from datetime import datetime
start_time = datetime.now()
# do your work here
end_time = datetime.now()
print(''Duration: {}''.format(end_time - start_time))
Salida de muestra, por ejemplo
Duration: 0:00:08.309267
o
Duration: 1 day, 1:51:24.269711
Actualización: Como mencionó JF Sebastian, este enfoque puede encontrar algunos casos difíciles con la hora local, por lo que es más seguro usar:
import time
from datetime import timedelta
start_time = time.monotonic()
end_time = time.monotonic()
print(timedelta(seconds=end_time - start_time))
Para usar la respuesta actualizada de metakermit para Python 2.7, necesitará el paquete monotonic .
El código sería el siguiente:
from datetime import timedelta
from monotonic import monotonic
start_time = monotonic()
end_time = monotonic()
print(timedelta(seconds=end_time - start_time))
Puede usar el perfil de perfil de python para medir el tiempo de CPU y, además, cuánto tiempo pasa dentro de cada función y cuántas veces se llama a cada función. Esto es muy útil si desea mejorar el rendimiento de su script sin saber por dónde empezar. Esta respuesta a otra pregunta SO es bastante buena. Siempre es bueno echar un vistazo a los documentos también.
Aquí hay un ejemplo de cómo perfilar un script usando cProfile desde una línea de comando:
$ python -m cProfile euler048.py
1007 function calls in 0.061 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.061 0.061 <string>:1(<module>)
1000 0.051 0.000 0.051 0.000 euler048.py:2(<lambda>)
1 0.005 0.005 0.061 0.061 euler048.py:2(<module>)
1 0.000 0.000 0.061 0.061 {execfile}
1 0.002 0.002 0.053 0.053 {map}
1 0.000 0.000 0.000 0.000 {method ''disable'' of ''_lsprof.Profiler objects}
1 0.000 0.000 0.000 0.000 {range}
1 0.003 0.003 0.003 0.003 {sum}
Realmente me gusta la respuesta de Paul McGuire, pero uso Python3. Así que para aquellos que estén interesados: aquí hay una modificación de su respuesta que funciona con Python 3 en * nix (me imagino que, bajo Windows, ese reloj () debería usarse en lugar de time ()):
#python3
import atexit
from time import time, strftime, localtime
from datetime import timedelta
def secondsToStr(elapsed=None):
if elapsed is None:
return strftime("%Y-%m-%d %H:%M:%S", localtime())
else:
return str(timedelta(seconds=elapsed))
def log(s, elapsed=None):
line = "="*40
print(line)
print(secondsToStr(), ''-'', s)
if elapsed:
print("Elapsed time:", elapsed)
print(line)
print()
def endlog():
end = time()
elapsed = end-start
log("End Program", secondsToStr(elapsed))
start = time()
atexit.register(endlog)
log("Start Program")
Si esto le resulta útil, aún debe votar de forma ascendente su respuesta en lugar de esta, ya que hizo la mayor parte del trabajo;).
Solo usa el módulo timeit
. Funciona con Python 2 y Python 3
import timeit
start = timeit.default_timer()
#ALL THE PROGRAM STATEMETNS
stop = timeit.default_timer()
execution_time = stop - start
print("Program Executed in "+execution_time) #It returns time in sec
Vuelve en segundos y puede tener su tiempo de ejecución. Simple, pero debe escribir esto en la función principal que inicia la ejecución del programa. Si desea obtener el tiempo de ejecución incluso cuando se produce un error, lleve el parámetro "Inicio" y calcule allí como
def sample_function(start,**kwargs):
try:
#your statements
Except:
#Except Statements
stop = timeit.default_timer()
execution_time = stop - start
print("Program Executed in "+execution_time)
También me gusta la respuesta de Paul McGuire y se me ocurrió una forma de administrador de contexto que se adaptaba más a mis necesidades.
import datetime as dt
import timeit
class TimingManager(object):
"""Context Manager used with the statement ''with'' to time some execution.
Example:
with TimingManager() as t:
# Code to time
"""
clock = timeit.default_timer
def __enter__(self):
"""
"""
self.start = self.clock()
self.log(''/n=> Start Timing: {}'')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
"""
"""
self.endlog()
return False
def log(self, s, elapsed=None):
"""Log current time and elapsed time if present.
:param s: Text to display, use ''{}'' to format the text with
the current time.
:param elapsed: Elapsed time to display. Dafault: None, no display.
"""
print s.format(self._secondsToStr(self.clock()))
if(elapsed is not None):
print ''Elapsed time: {}/n''.format(elapsed)
def endlog(self):
"""Log time for the end of execution with elapsed time.
"""
self.log(''=> End Timing: {}'', self.now())
def now(self):
"""Return current elapsed time as hh:mm:ss string.
:return: String.
"""
return str(dt.timedelta(seconds = self.clock() - self.start))
def _secondsToStr(self, sec):
"""Convert timestamp to h:mm:ss string.
:param sec: Timestamp.
"""
return str(dt.datetime.fromtimestamp(sec))
Timeit es una clase en python utilizada para calcular el tiempo de ejecución de pequeños bloques de código.
Default_timer es un método en esta clase que se usa para medir el tiempo del reloj de pared y no el tiempo de ejecución de la CPU. Por lo tanto, la ejecución de otro proceso podría interferir con esto. Por lo tanto es útil para pequeños bloques de código.
Una muestra del código es la siguiente:
from timeit import default_timer as timer
start= timer()
#some logic
end = timer()
print("Time taken:", end-start)
Usé una función muy simple para cronometrar una parte de la ejecución del código:
import time
def timing():
start_time = time.time()
return lambda x: print("[{:.2f}s] {}".format(time.time() - start_time, x))
Y para usarlo, simplemente llámelo antes del código para medir y recuperar la función de tiempo, luego llame la función después del código con comentarios, y la hora aparecerá delante de los comentarios, por ejemplo:
t = timing()
train = pd.read_csv(''train.csv'',
dtype={
''id'': str,
''vendor_id'': str,
''pickup_datetime'': str,
''dropoff_datetime'': str,
''passenger_count'': int,
''pickup_longitude'': np.float64,
''pickup_latitude'': np.float64,
''dropoff_longitude'': np.float64,
''dropoff_latitude'': np.float64,
''store_and_fwd_flag'': str,
''trip_duration'': int,
},
parse_dates = [''pickup_datetime'', ''dropoff_datetime''],
)
t("Loaded {} rows data from ''train''".format(len(train)))
Entonces la salida se verá así:
[9.35s] Loaded 1458644 rows data from ''train''
Me siento un poco elegante de esta manera.
Utilice line_profiler .
line_profiler perfilará el tiempo que tardan en ejecutarse las líneas individuales de código. El perfilador se implementa en C a través de Cython para reducir la sobrecarga del perfilado.
from line_profiler import LineProfiler
import random
def do_stuff(numbers):
s = sum(numbers)
l = [numbers[i]/43 for i in range(len(numbers))]
m = [''hello''+str(numbers[i]) for i in range(len(numbers))]
numbers = [random.randint(1,100) for i in range(1000)]
lp = LineProfiler()
lp_wrapper = lp(do_stuff)
lp_wrapper(numbers)
lp.print_stats()
Los resultados serán:
Timer unit: 1e-06 s
Total time: 0.000649 s
File: <ipython-input-2-2e060b054fea>
Function: do_stuff at line 4
Line # Hits Time Per Hit % Time Line Contents
==============================================================
4 def do_stuff(numbers):
5 1 10 10.0 1.5 s = sum(numbers)
6 1 186 186.0 28.7 l = [numbers[i]/43 for i in range(len(numbers))]
7 1 453 453.0 69.8 m = [''hello''+str(numbers[i]) for i in range(len(numbers))]
timing.py
este módulo timing.py
en mi propio directorio de site-packages
, y simplemente inserto el import timing
en la parte superior de mi módulo:
import atexit
from time import clock
def secondsToStr(t):
return "%d:%02d:%02d.%03d" % /
reduce(lambda ll,b : divmod(ll[0],b) + ll[1:],
[(t*1000,),1000,60,60])
line = "="*40
def log(s, elapsed=None):
print line
print secondsToStr(clock()), ''-'', s
if elapsed:
print "Elapsed time:", elapsed
print line
print
def endlog():
end = clock()
elapsed = end-start
log("End Program", secondsToStr(elapsed))
def now():
return secondsToStr(clock())
start = clock()
atexit.register(endlog)
log("Start Program")
También puedo llamar a timing.log
desde mi programa si hay etapas significativas dentro del programa que quiero mostrar. Pero solo con incluir el import timing
se imprimirán las horas de inicio y finalización, y el tiempo total transcurrido. (Perdone mi función oscura de secondsToStr
, solo da formato a un número de segundos en coma flotante a la forma hh: mm: ss.sss).
Nota: Puede encontrar una versión de Python 3 del código anterior here o here .
hora.clock ()
En desuso desde la versión 3.3: El comportamiento de esta función depende de la plataforma: use perf_counter () o process_time () en su lugar, según sus requisitos, para tener un comportamiento bien definido.
time.perf_counter ()
Devuelva el valor (en fracciones de segundos) de un contador de rendimiento, es decir, un reloj con la resolución más alta disponible para medir una duración corta. Incluye el tiempo transcurrido durante la suspensión y se aplica a todo el sistema.
time.process_time ()
Devuelva el valor (en segundos fraccionarios) de la suma del sistema y el tiempo de CPU del usuario del proceso actual. No incluye el tiempo transcurrido durante el sueño.
start = time.process_time()
... do something
elapsed = (time.process_time() - start)
from time import time
start_time = time()
...
end_time = time()
time_taken = end_time - start_time # time_taken is in seconds
hours, rest = divmod(time_taken,3600)
minutes, seconds = divmod(rest, 60)
import time
start_time = time.clock()
main()
print time.clock() - start_time, "seconds"
time.clock()
devuelve el tiempo del procesador, lo que nos permite calcular solo el tiempo utilizado por este proceso (en Unix de todos modos). La documentación dice que "en cualquier caso, esta es la función que se debe usar para la evaluación comparativa de algoritmos de Python o de temporización"