C'est le contour d'un programme 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)
Je continue juste à obtenir "le nom global foo n'est pas défini" ..... Quelqu'un peut-il m'aider? Merci!
Les extraits de code doivent être autonomes. Ils ne peuvent pas faire de références externes. Vous devez définir vos valeurs dans la chaîne d'instructions ou la chaîne d'installation:
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))
Mieux encore, réécrivez votre code pour ne pas utiliser de valeurs globales.
Les fonctions peuvent utiliser des arguments dans timeit
s'ils sont créés à l'aide de fermetures, nous pouvons ajouter ces comportements en les encapsulant dans une autre fonction.
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)
ou plus court, nous pouvons utiliser functools.partial au lieu de la déclaration de fermetures explicites
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)
En supposant que votre nom de fichier de module est 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)
Votre fonction doit être définie dans la chaîne de configuration. Un bon moyen de le faire est de configurer votre code dans un module, il vous suffit donc de le faire.
t = timeit.Timer("foo(num1, num2)", "from myfile import foo")
t.timeit(5)
Sinon, vous devrez définir toute la configuration en tant que chaîne à l'intérieur de l'instruction de configuration.
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)
Quelque chose de génial que je viens de découvrir est un raccourci pour iPython qui utilise cProfile.
def foo(x, y):
print x*y
%prun foo("foo", 100)
Je crée généralement une fonction supplémentaire:
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"))
Voici un exemple montrant comment compartimenter la routine de chronométrage sans appeler de 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
Vous pouvez même généraliser ceci si vous souhaitez utiliser la même fonction timeit
pour chronométrer d'autres fonctions. Voici un exemple avec votre exemple de routine main()
:
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
Je jouais avec la synchronisation dans Python 3.7 aujourd'hui et j'essayais de transmettre des fonctions et des variables à la minuterie. C'est ce que je suis venu avec.
import re
text = "This is a test of the emergency broadcast system"
def regex(text):
return re.sub(r"(\s)\1{1,}", r"\1", text)
def loop_while(text):
if " " in text:
while " " in text:
text = text.replace(" ", " ")
return text
if __== "__main__":
import timeit
callable_functions = [item for item in locals().items() if callable(item[1])]
for func_name, func in callable_functions:
elapsed_time = timeit.timeit(f"{func_name}(text)", globals=globals(), number=100000)
print(f"{func_name}: {elapsed_time} \n{func(text)}\n")
Cela génère:
regex: 1.378352418
Ceci est un test du système de diffusion d'urgenceloop_while: 0.15858950299999997
Ceci est un test de l'urgence système de diffusion
Il suffit ensuite de tester une nouvelle version pour ajouter une nouvelle fonction. Quelque chose comme:
def split_join(text):
return " ".join(text.split())
Maintenant, il affiche:
regex: 1.378352418
Ceci est un test du système de diffusion d'urgenceloop_while: 0.15858950299999997
Ceci est un test du système de diffusion d'urgencesplit_join: 0.05700970800000005
Ceci est un test du système de diffusion d'urgence
Cela devrait fonctionner:
import timeit
def f(x,y):
return x*y
x = 5
y = 7
print(timeit.timeit(stmt='f(x,y)',
setup='from __main__ import f, x, y',
number=1000))
Je préfère créer une classe static
avec toutes les données prêtes à être récupérées avant l'exécution du chronomètre.
Autre remarque, il est préférable d'effectuer des tests en mode fonctionnel plutôt qu'en espace global, l'espace global ne tirant pas parti de
FAST_LOAD
Pourquoi le code Python s'exécute-t-il plus rapidement dans une fonction?
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)