Medir el tiempo de una función con argumentos en Python

Estoy tratando de medir el tiempo de raw_queries(...) , hasta ahora sin éxito. Encontré que debería usar el módulo timeit. El problema es que no puedo (= no sé cómo) pasar los argumentos a la función desde el entorno.

Nota importante: antes de llamar a raw_queries , tenemos que ejecutar phase2() (inicialización de entorno).

Nota al margen: El código está en Python 3.

 def raw_queries(queries, nlp): """ Submit queries without getting visual response """ for q in queries: nlp.query(q) def evaluate_queries(queries, nlp): """ Measure the time that the queries need to return their results """ t = Timer("raw_queries(queries, nlp)", "?????") print(t.timeit()) def phase2(): """ Load dictionary to memory and subsequently submit queries """ # prepare Linguistic Processor to submit it the queries all_files = get_files() b = LinguisticProcessor(all_files) b.loadDictionary() # load the queries queries_file = 'queries.txt' queries = load_queries(queries_file) if __name__ == '__main__': phase2() 

Gracias por cualquier ayuda.

ACTUALIZACIÓN: Podemos llamar a phase2() usando el segundo argumento de Timer . El problema es que necesitamos los argumentos (queries, nlp) del entorno.

ACTUALIZACIÓN: la mejor solución hasta el momento, con la ayuda de unutbu (solo lo que ha cambiado):

 def evaluate_queries(): """ Measure the time that the queries need to return their results """ t = Timer("main.raw_queries(queries, nlp)", "import main;\ (queries,nlp)=main.phase2()") sf = 'Execution time: {} ms' print(sf.format(t.timeit(number=1000))) def phase2(): ... return queries, b def main(): evaluate_queries() if __name__ == '__main__': main() 

Primero, nunca use el módulo de tiempo para funciones de tiempo. Puede conducir fácilmente a conclusiones erróneas. Ver timeit versus timing decorator para un ejemplo.

La forma más fácil de cronometrar una llamada de función es usar el comando% timeit de IPython’s. Allí, simplemente inicia una sesión interactiva de IPython, llama a phase2() , define queries y luego ejecuta

 %timeit raw_queries(queries,nlp) 

La segunda forma más fácil que conozco de usar timeit es llamarlo desde la línea de comandos:

 python -mtimeit -s"import test; queries=test.phase2()" "test.raw_queries(queries)" 

(En el comando anterior, asumo que el script se llama test.py )

El idioma aquí es

 python -mtimeit -s"SETUP_COMMANDS" "COMMAND_TO_BE_TIMED" 

Para poder pasar queries a la llamada a la función raw_queries , debe definir la variable de queries . En el código que ha publicado, las queries se definen en phase2() , pero solo localmente. Por lo tanto, para configurar las queries como una variable global, debe hacer algo como tener queries retorno de phase2 :

 def phase2(): ... return queries 

Si no quieres estropear la phase2 esta manera, crea una función ficticia:

 def phase3(): # Do stuff like phase2() but return queries return queries 

Normalmente, utilizarías timeit .

Los ejemplos están aquí y aquí .

También tenga en cuenta:

De forma predeterminada, timeit () desactiva temporalmente la recolección de basura durante el tiempo. La ventaja de este enfoque es que hace que los tiempos independientes sean más comparables. Esta desventaja es que GC puede ser un componente importante del desempeño de la función que se mide.

O puede escribir su propio temporizador personalizado utilizando el módulo de tiempo .

Si va con un temporizador personalizado, recuerde que debe usar time.clock () en windows y time.time () en otras plataformas. (Timeit elige internamente)

 import sys import time # choose timer to use if sys.platform.startswith('win'): default_timer = time.clock else: default_timer = time.time start = default_timer() # do something finish = default_timer() elapsed = (finish - start) 

No estoy seguro de esto, nunca lo he usado, pero por lo que he leído debería ser algo como esto:

 .... t = Timer("raw_queries(queries, nlp)", "from __main__ import raw_queries") print t.timeit() 

Tomé esto de http://docs.python.org/library/timeit.html (si esto ayuda).

La función de temporizador personalizada puede ser una solución:

 import time def timer(fun,*args): start = time.time() ret = fun(*args) end = time.time() return (ret, end-start) 

Utilizando así:

 >>> from math import sin >>> timer(sin, 0.5) (0.47942553860420301, 6.9141387939453125e-06) 

Significa que el sin devolvió 0.479... y tomó 6.9e-6 segundos. Asegúrese de que sus funciones se ejecuten el tiempo suficiente si desea obtener números confiables (no como en el ejemplo anterior).

No lo dices, pero ¿estás por casualidad intentando que el código vaya más rápido? Si es así, te sugiero que no te concentres en una rutina en particular e intentes cronometrarla. Incluso si obtienes un número, realmente no te dirá qué arreglar. Si puede pausar el progtwig varias veces bajo el IDE y examinar su estado, incluida la stack de llamadas, le dirá qué se está demorando y por qué. Aquí hay un enlace que brinda una breve explicación de cómo y por qué funciona. *

* Cuando sigue el enlace, es posible que deba ir al final de la página anterior de respuestas. SO está teniendo problemas para seguir un enlace a una respuesta.