una resueltos propias otra matematicas lista globales funciones funcion ejercicios dentro definir cerrar python testing time profiling

resueltos - lista de funciones de python



Cronometraje preciso de las funciones en python (7)

Estoy programando en python en Windows y me gustaría medir con precisión el tiempo que tarda en ejecutarse una función. He escrito una función "time_it" que toma otra función, la ejecuta y devuelve el tiempo que tardó en ejecutarse.

def time_it(f, *args): start = time.clock() f(*args) return (time.clock() - start)*1000

Llamo esto 1000 veces y promedie el resultado. (la constante 1000 al final es dar la respuesta en milisegundos).

Esta función parece funcionar, pero tengo la sensación molesta de que estoy haciendo algo mal, y que al hacerlo de esta manera estoy usando más tiempo del que realmente usa la función cuando está funcionando.

¿Hay una manera más estándar o aceptada de hacer esto?

Cuando cambié mi función de prueba para llamar a una impresión para que demore más, mi función time_it devuelve un promedio de 2.5 ms mientras que cProfile.run (''f ()'' regresa y promedia de 7.0 ms. Pensé que mi función sobreestimaría el tiempo en todo caso, ¿qué está pasando aquí?

Una nota adicional, es el tiempo relativo de funciones comparadas entre sí que me importa, no el tiempo absoluto ya que esto obviamente variará dependiendo del hardware y otros factores.


En lugar de escribir su propio código de creación de perfiles, le sugiero que consulte los perfiladores de Python incorporados ( profile o profile cProfile , según sus necesidades): http://docs.python.org/library/profile.html


Este código es muy inexacto

total= 0 for i in range(1000): start= time.clock() function() end= time.clock() total += end-start time= total/1000

Este código es menos inexacto

start= time.clock() for i in range(1000): function() end= time.clock() time= (end-start)/1000

El muy inexacto sufre de sesgo de medición si el tiempo de ejecución de la función es cercano a la precisión del reloj. La mayoría de los tiempos medidos son meramente números aleatorios entre 0 y unos pocos tics del reloj.

Dependiendo de la carga de trabajo de su sistema, el "tiempo" que observa desde una sola función puede ser completamente un artefacto de la programación del sistema operativo y otros gastos indirectos incontrolables.

La segunda versión (menos imprecisa) tiene menos sesgo de medición. Si su función es realmente rápida, puede necesitar ejecutarla 10.000 veces para amortiguar la programación del sistema operativo y otros gastos generales.

Ambos son, por supuesto, terriblemente engañosos. El tiempo de ejecución para su programa, como un todo, no es la suma de los tiempos de ejecución de la función. Solo puedes usar los números para comparaciones relativas. No son medidas absolutas que transmiten mucho significado.


Esto es más limpio

from contextlib import contextmanager import time @contextmanager def timeblock(label): start = time.clock() try: yield finally: end = time.clock() print (''{} : {}''.format(label, end - start)) with timeblock("just a test"): print "yippee"


Puede crear un decorador "timeme" como ese

import time def timeme(method): def wrapper(*args, **kw): startTime = int(round(time.time() * 1000)) result = method(*args, **kw) endTime = int(round(time.time() * 1000)) print(endTime - startTime,''ms'') return result return wrapper @timeme def func1(a,b,c = ''c'',sleep = 1): time.sleep(sleep) print(a,b,c) func1(''a'',''b'',''c'',0) func1(''a'',''b'',''c'',0.5) func1(''a'',''b'',''c'',0.6) func1(''a'',''b'',''c'',1)


Si desea sincronizar un método de python, incluso si el bloque que mide puede arrojar, un buen enfoque es usarlo with instrucción. Definir alguna clase de Timer como

import time class Timer: def __enter__(self): self.start = time.clock() return self def __exit__(self, *args): self.end = time.clock() self.interval = self.end - self.start

Entonces quizás desee programar un método de conexión que pueda arrojar. Utilizar

import httplib with Timer() as t: conn = httplib.HTTPConnection(''google.com'') conn.request(''GET'', ''/'') print(''Request took %.03f sec.'' % t.interval)

__exit()__ método __exit()__ incluso si la solicitud de conexión falla. Más precisamente, harías que uses, try finally ver el resultado en caso de que arroje, como con

try: with Timer() as t: conn = httplib.HTTPConnection(''google.com'') conn.request(''GET'', ''/'') finally: print(''Request took %.03f sec.'' % t.interval)

Más detalles aquí.


Similar a la respuesta de @ AlexMartelli

import timeit timeit.timeit(fun, number=10000)

puede hacer el truco


Use el módulo timeit de la biblioteca estándar de Python.

Uso básico:

from timeit import Timer # first argument is the code to be run, the second "setup" argument is only run once, # and it not included in the execution time. t = Timer("""x.index(123)""", setup="""x = range(1000)""") print t.timeit() # prints float, for example 5.8254 # ..or.. print t.timeit(1000) # repeat 1000 times instead of the default 1million