tiempo sacar reloj libreria ejecucion cronometro como python performance measure timeit

sacar - ¿Medido el tiempo transcurrido en Python?



tiempo en python (21)

Sólo Python 3:

Dado que time.clock () está en desuso a partir de Python 3.3 , deseará usar perf_counter para la temporización de todo el sistema, o process_time para la temporización de todo el proceso, de la misma manera que solía usar el time.clock() :

import time t = time.process_time() #do some stuff elapsed_time = time.process_time() - t

La nueva función process_time no incluirá el tiempo transcurrido durante la suspensión.

Lo que quiero es comenzar a contar el tiempo en algún lugar de mi código y luego obtener el tiempo pasado, para medir el tiempo que llevó ejecutar algunas funciones. Creo que estoy usando mal el módulo timeit, pero los documentos son confusos para mí.

import timeit start = timeit.timeit() print "hello" end = timeit.timeit() print end - start


(Solo con Ipython) puede usar %timeit para medir el tiempo de procesamiento promedio:

def foo(): print "hello"

y entonces:

%timeit foo()

el resultado es algo como:

10000 loops, best of 3: 27 µs per loop


Aquí están mis conclusiones después de leer muchas buenas respuestas aquí, así como algunos otros artículos.

Primero, siempre desea usar timeit y no time.time (y en muchos casos, API de contador) porque

  1. timeit selecciona el mejor temporizador disponible en su sistema operativo y la versión de Python.
  2. timeit desactiva la recolección de basura, sin embargo, esto no es algo que puede o no desear.

Ahora el problema es que timeit no es tan fácil de usar porque necesita configuración y las cosas se ponen feas cuando tienes muchas importaciones. Lo ideal es que solo quieras un decorador o que uses with bloqueo y medición. Desafortunadamente, no hay nada integrado disponible para esto, así que creé debajo del pequeño módulo de utilidad.

Módulo de utilidad de sincronización

# utils.py from functools import wraps import gc import timeit def MeasureTime(f): @wraps(f) def _wrapper(*args, **kwargs): gcold = gc.isenabled() gc.disable() start_time = timeit.default_timer() try: result = f(*args, **kwargs) finally: elapsed = timeit.default_timer() - start_time if gcold: gc.enable() print(''Function "{}": {}s''.format(f.__name__, elapsed)) return result return _wrapper class MeasureBlockTime: def __init__(self,name="(block)", no_print = False, disable_gc = True): self.name = name self.no_print = no_print self.disable_gc = disable_gc def __enter__(self): if self.disable_gc: self.gcold = gc.isenabled() gc.disable() self.start_time = timeit.default_timer() def __exit__(self,ty,val,tb): self.elapsed = timeit.default_timer() - self.start_time if self.disable_gc and self.gcold: gc.enable() if not self.no_print: print(''Function "{}": {}s''.format(self.name, self.elapsed)) return False #re-raise any exceptions

Cómo programar funciones

Ahora puedes programar cualquier función simplemente poniendo un decorador delante de ella:

import utils @utils.MeasureTime def MyBigFunc(): #do something time consuming for i in range(10000): print(i)

Cómo codificar los bloques de tiempo

Si desea cronometrar parte del código, simplemente póngalo dentro with bloque:

import utils #somewhere in my code with utils.MeasureBlockTime("MyBlock"): #do something time consuming for i in range(10000): print(i) # rest of my code

Ventajas

Hay varias versiones de media copia flotando alrededor, así que quiero señalar algunos aspectos destacados:

  1. Use el temporizador de timeit en lugar de time.time por las razones descritas anteriormente.
  2. Desactivar GC durante el tiempo.
  3. El decorador acepta funciones con parámetros con nombre o sin nombre.
  4. Posibilidad de deshabilitar la impresión en tiempo de bloque (usar with utils.MeasureBlockTime() as t y luego t.elapsed ).
  5. Posibilidad de mantener gc habilitado para la temporización de bloque.

Aquí hay otro administrador de contexto para el código de tiempo:

Uso:

from benchmark import benchmark with benchmark("Test 1+1"): 1+1 => Test 1+1 : 1.41e-06 seconds

o, si necesitas el valor de tiempo

with benchmark("Test 1+1") as b: 1+1 print(b.time) => Test 1+1 : 7.05e-07 seconds 7.05233786763e-07

benchmark.py :

from timeit import default_timer as timer class benchmark(object): def __init__(self, msg, fmt="%0.3g"): self.msg = msg self.fmt = fmt def __enter__(self): self.start = timer() return self def __exit__(self, *args): t = timer() - self.start print(("%s : " + self.fmt + " seconds") % (self.msg, t)) self.time = t

Adaptado de dabeaz.blogspot.fr/2010/02/…


Aquí hay una pequeña clase de temporizador que devuelve la cadena "hh: mm: ss":

class Timer: def __init__(self): self.start = time.time() def restart(self): self.start = time.time() def get_time_hhmmss(self): end = time.time() m, s = divmod(end - self.start, 60) h, m = divmod(m, 60) time_str = "%02d:%02d:%02d" % (h, m, s) return time_str

Uso:

# Start timer my_timer = Timer() # ... do something # Get time string: time_hhmmss = my_timer.get_time_hhmmss() print("Time elapsed: %s" % time_hhmmss ) # ... use the timer again my_timer.restart() # ... do something # Get time: time_hhmmss = my_timer.get_time_hhmmss() # ... etc


Dada una función que te gustaría cronometrar,

test.py:

def foo(): # print "hello" return "hello"

la forma más fácil de usar timeit es llamarlo desde la línea de comando:

% python -mtimeit -s''import test'' ''test.foo()'' 1000000 loops, best of 3: 0.254 usec per loop

No intente usar time.time o time.clock (ingenuamente) para comparar la velocidad de las funciones. Pueden dar resultados engañosos .

PD. No coloque declaraciones impresas en una función que desee programar; De lo contrario, el tiempo medido dependerá de la velocidad del terminal .


El uso de time.time para medir la ejecución le brinda el tiempo total de ejecución de sus comandos, incluido el tiempo de ejecución empleado por otros procesos en su computadora. Es el momento en que el usuario se da cuenta, pero no es bueno si desea comparar diferentes fragmentos de código / algoritmos / funciones / ...

Más información sobre timeit :

Si desea una visión más profunda de los perfiles:

Actualización : Utilicé http://pythonhosted.org/line_profiler/ mucho durante el último año y lo encuentro muy útil y recomiendo usarlo en lugar del módulo de perfil de Pythons.


Es divertido hacer esto con un administrador de contexto que recuerda automáticamente la hora de inicio al ingresar a un bloque with , y luego congela la hora de finalización en la salida del bloque. Con un pequeño truco, incluso puede obtener un recuento de tiempo transcurrido dentro del bloque desde la misma función de administrador de contexto.

La biblioteca central no tiene esto (pero probablemente debería). Una vez en su lugar, puedes hacer cosas como:

with elapsed_timer() as elapsed: # some lengthy code print( "midpoint at %.2f seconds" % elapsed() ) # time so far # other lengthy code print( "all done at %.2f seconds" % elapsed() )

Aquí está el código de contextmanager suficiente para hacer el truco:

from contextlib import contextmanager from timeit import default_timer @contextmanager def elapsed_timer(): start = default_timer() elapser = lambda: default_timer() - start yield lambda: elapser() end = default_timer() elapser = lambda: end-start

Y algún código demo ejecutable:

import time with elapsed_timer() as elapsed: time.sleep(1) print(elapsed()) time.sleep(2) print(elapsed()) time.sleep(3)

Tenga en cuenta que al diseñar esta función, el valor de retorno de elapsed() se congela en la salida del bloque, y las llamadas posteriores devuelven la misma duración (de aproximadamente 6 segundos en este ejemplo de juguete).


Es una respuesta súper tardía, pero tal vez tenga un propósito para alguien. Esta es una forma de hacerlo que creo que es super limpia.

import time def timed(fun, *args): s = time.time() r = fun(*args) print(''{} execution took {} seconds.''.format(fun.__name__, time.time()-s)) return(r) timed(print, "Hello")

Tenga en cuenta que "imprimir" es una función en Python 3 y no en Python 2.7. Sin embargo, funciona con cualquier otra función. ¡Aclamaciones!


Hice una biblioteca para esto, si quieres medir una función, puedes hacerlo así

from pythonbenchmark import compare, measure import time a,b,c,d,e = 10,10,10,10,10 something = [a,b,c,d,e] @measure def myFunction(something): time.sleep(0.4) @measure def myOptimizedFunction(something): time.sleep(0.2) myFunction(input) myOptimizedFunction(input)

https://github.com/Karlheinzniebuhr/pythonbenchmark


La única manera en que puedo pensar es usando time.time() .

import time start = time.time() sleep(5) #just to give it some delay to show it working finish = time.time() elapsed = finish - start print(elapsed)

Espero que eso ayude.


Los módulos Python cProfile y pstats ofrecen una gran compatibilidad para medir el tiempo transcurrido en ciertas funciones sin tener que agregar ningún código alrededor de las funciones existentes.

Por ejemplo, si tiene un script de python timeFunctions.py:

import time def hello(): print "Hello :)" time.sleep(0.1) def thankyou(): print "Thank you!" time.sleep(0.05) for idx in range(10): hello() for idx in range(100): thankyou()

Para ejecutar el generador de perfiles y generar estadísticas para el archivo, simplemente puede ejecutar:

python -m cProfile -o timeStats.profile timeFunctions.py

Lo que está haciendo es utilizar el módulo cProfile para perfilar todas las funciones en timeFunctions.py y recopilar las estadísticas en el archivo timeStats.profile. Tenga en cuenta que no tuvimos que agregar ningún código al módulo existente (timeFunctions.py) y esto se puede hacer con cualquier módulo.

Una vez que tenga el archivo de estadísticas, puede ejecutar el módulo pstats de la siguiente manera:

python -m pstats timeStats.profile

Esto ejecuta el navegador de estadísticas interactivo que te brinda una gran funcionalidad. Para su caso de uso particular, solo puede verificar las estadísticas de su función. En nuestro ejemplo, la comprobación de estadísticas para ambas funciones nos muestra lo siguiente:

Welcome to the profile statistics browser. timeStats.profile% stats hello <timestamp> timeStats.profile 224 function calls in 6.014 seconds Random listing order was used List reduced from 6 to 1 due to restriction <''hello''> ncalls tottime percall cumtime percall filename:lineno(function) 10 0.000 0.000 1.001 0.100 timeFunctions.py:3(hello) timeStats.profile% stats thankyou <timestamp> timeStats.profile 224 function calls in 6.014 seconds Random listing order was used List reduced from 6 to 1 due to restriction <''thankyou''> ncalls tottime percall cumtime percall filename:lineno(function) 100 0.002 0.000 5.012 0.050 timeFunctions.py:7(thankyou)

El ejemplo ficticio no hace mucho, pero le da una idea de lo que se puede hacer. La mejor parte de este enfoque es que no tengo que editar ninguno de mis códigos existentes para obtener estos números y, obviamente, ayuda con los perfiles.


Mejor use timeit simplemente: (ejecuta varias ejecuciones para el mismo comando y le proporciona los resultados).

El ejemplo se da a continuación:

%timeit import pandas as pd


Prefiero esto. timeit doc es demasiado confuso

from datetime import datetime start_time = datetime.now() # INSERT YOUR CODE time_elapsed = datetime.now() - start_time print(''Time elapsed (hh:mm:ss.ms) {}''.format(time_elapsed))

Tenga en cuenta que aquí no hay ningún formato, solo escribí hh:mm:ss en la impresión para que se pueda interpretar time_elapsed


Puedes usar timeit.

Aquí hay un ejemplo sobre cómo probar naive_func que toma parámetros usando Python REPL:

>>> import timeit >>> def naive_func(x): ... a = 0 ... for i in range(a): ... a += i ... return a >>> def wrapper(func, *args, **kwargs): ... def wrapper(): ... return func(*args, **kwargs) ... return wrapper >>> wrapped = wrapper(naive_func, 1_000) >>> timeit.timeit(wrapped, number=1_000_000) 0.4458435332577161

No necesita la función de envoltura si la función no tiene ningún parámetro.


Si solo desea medir el tiempo de reloj de pared transcurrido entre dos puntos, puede usar time.time() :

import time start = time.time() print("hello") end = time.time() print(end - start)

Esto da el tiempo de ejecución en segundos.

Otra opción desde 3.3 podría ser usar perf_counter o process_time , dependiendo de sus requisitos. Antes de 3.3 se recomendó usar time.clock (gracias Amber ). Sin embargo, actualmente está en desuso:

En Unix, devuelva el tiempo actual del procesador como un número de punto flotante expresado en segundos. La precisión, y de hecho la definición misma del significado de "tiempo de procesador", depende de la función C del mismo nombre.

En Windows, esta función devuelve los segundos de reloj de pared transcurridos desde la primera llamada a esta función, como un número de punto flotante, basado en la función Win32 QueryPerformanceCounter() . La resolución suele ser mejor que un microsegundo.

En desuso desde la versión 3.3 : El comportamiento de esta función depende de la plataforma: use perf_counter() o process_time() lugar , según sus requisitos, para tener un comportamiento bien definido.


También podemos convertir el tiempo en tiempo legible por humanos.

import time, datetime start = time.clock() def num_multi1(max): result = 0 for num in range(0, 1000): if (num % 3 == 0 or num % 5 == 0): result += num print "Sum is %d " % result num_multi1(1000) end = time.clock() value = end - start timestamp = datetime.datetime.fromtimestamp(value) print timestamp.strftime(''%Y-%m-%d %H:%M:%S'')


Una forma más de usar timeit :

from timeit import timeit def func(): return 1 + 1 time = timeit(func, number=1) print(time)


Usa el modificador de perfiles. Da un perfil muy detallado.

import profile profile.run(''main()'')

produce algo como:

5 function calls in 0.047 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.000 0.000 :0(exec) 1 0.047 0.047 0.047 0.047 :0(setprofile) 1 0.000 0.000 0.000 0.000 <string>:1(<module>) 0 0.000 0.000 profile:0(profiler) 1 0.000 0.000 0.047 0.047 profile:0(main()) 1 0.000 0.000 0.000 0.000 two_sum.py:2(twoSum)

Lo he encontrado muy informativo.


Utilice timeit.default_timer lugar de timeit.timeit . El primero proporciona automáticamente el mejor reloj disponible en su plataforma y versión de Python:

from timeit import default_timer as timer start = timer() # ... end = timer() print(end - start) # Time in seconds, e.g. 5.38091952400282

timeit.default_timer se asigna a time.time () o time.clock () según el sistema operativo. En Python 3.3+, default_timer es time.perf_counter() en todas las plataformas. Ver Python - time.clock () vs. time.time () - ¿exactitud?

Ver también:


en python3:

from time import sleep, perf_counter as pc t0 = pc() sleep(1) print(pc()-t0)

Elegante y corto.