the - time python 3
cómo pasar los parámetros de una función cuando se usa timeit.Timer() (7)
Este es el esquema de un programa simple
# some pre-defined constants
A = 1
B = 2
# function that does something critical
def foo(num1, num2):
# do something
# main program.... do something to A and B
for i in range(20):
# do something to A and B
# and update A and B during each iteration
import timeit
t = timeit.Timer(stmt="foo(num1,num2)")
print t.timeit(5)
Sigo recibiendo "nombre global foo no está definido" ..... ¿Alguien puede ayudarme en esto? ¡Gracias!
Los fragmentos de código deben ser independientes: no pueden hacer referencias externas. Debe definir sus valores en la línea de instrucción o cadena de configuración:
import timeit
setup = """
A = 1
B = 2
def foo(num1, num2):
pass
def mainprog():
global A,B
for i in range(20):
# do something to A and B
foo(A, B)
"""
t = timeit.Timer(stmt="mainprog()" setup=setup)
print(t.timeit(5))
Mejor aún, reescriba su código para no usar valores globales.
Su función debe definirse en la cadena de configuración. Una buena forma de hacerlo es configurar tu código en un módulo, por lo que tienes que hacer
t = timeit.Timer("foo(num1, num2)", "from myfile import foo")
t.timeit(5)
De lo contrario, deberá definir toda la configuración como una cadena dentro de la declaración de configuración.
setup = """
# some pre-defined constants
A = 1
B = 2
# function that does something critical
def foo(num1, num2):
# do something
# main program.... do something to A and B
for i in range(20):
# do something to A and B
# and update A and B during each iteration
"""
t = timeit.Timer("foo(num1, num2)", setup)
t.timeit(5)
Algo impresionante que acabo de descubrir es un atajo para iPython que usa cProfile.
def foo(x, y):
print x*y
%prun foo("foo", 100)
Supongamos que el nombre de archivo de su módulo es test.py
# some pre-defined constants
A = 1
B = 2
# function that does something critical
def foo(n, m):
pass
# main program.... do something to A and B
for i in range(20):
pass
import timeit
t = timeit.Timer(stmt="test.foo(test.A, test.B)", setup="import test")
print t.timeit(5)
Por lo general, creo una función adicional:
def f(x,y):
return x*y
v1 = 10
v2 = 20
def f_test():
f(v1,v2)
print(timeit.timeit("f_test()", setup="from __main__ import f_test"))
Las funciones pueden usar argumentos en timeit
si se crean usando cierres, podemos agregar estos comportamientos envolviéndolos en otra función.
def foo(num1, num2):
def _foo():
# do something to num1 and num2
pass
return _foo
A = 1
B = 2
import timeit
t = timeit.Timer(foo(A,B))
print t.timeit(5)
o más corto, podemos usar functools.partial en lugar de declaración explícita de cierres
def foo(num1, num2):
# do something to num1 and num2
pass
A = 1
B = 2
import timeit, functools
t = timeit.Timer(functools.partial(foo, A, B))
print t.timeit(5)
Aquí hay un ejemplo de cómo dividir en compartimentos la rutina de tiempos, sin llamar a los globales
def foo(a, b):
''''''Do something to `a` and `b`''''''
return a + b
def time_foo():
''''''Create timer object simply without using global variables''''''
import timeit
_foo = foo
a = 1
b = 2
# Get `Timer` oject, alternatively just get time with `timeit.timeit()`
t = timeit.Timer(''_foo(a, b)'', globals=locals())
return t
Incluso podría generalizar esto si quisiera usar la misma función timeit
para timeit
otras funciones. Aquí hay un ejemplo con su rutina main()
ejemplo:
def foo1(a, b):
''''''Add `a` and `b`''''''
return a + b
def foo2(a, b):
''''''More math on `a` and `b`''''''
return (a**2 * b)**2
def time_foo(func, **kwargs):
''''''Create timer object simply without using global variables''''''
import timeit
return timeit.timeit(''func(**kwargs)'', globals=locals())
def run():
''''''Modify inputs to foo and see affect on execution time''''''
a = 1
b = 2
for i in range(10):
# Update `a` and `b`
a += 1
b += 2
# Pass args to foo as **kwargs dict
print(''foo1 time: '', time_foo(foo1, **{''a'':a, ''b'':b}))
print(''foo2 time: '', time_foo(foo2, **{''a'':a, ''b'':b}))
return None
Prefiero crear una clase static
con todos los datos listos para ser recogidos antes de ejecutar el temporizador.
Otra nota, es mejor hacer ejecuciones de prueba en lugar de en el espacio global, ya que el espacio global no se está aprovechando de
FAST_LOAD
¿Por qué el código de Python se ejecuta más rápido en una función?
class Data(object):
"""Data Creation"""
x = [i for i in range(0, 10000)]
y = tuple([i for i in range(0, 10000)])
def __init__(self):
pass
import timeit
def testIterator(x):
for i in range(10000):
z = i
print timeit.timeit("testIterator(Data.x)", setup="from __main__ import testIterator, Data", number=50)
print timeit.timeit("testIterator(Data.y)", setup="from __main__ import testIterator, Data", number=50)