Après tout, perf_counter ()
est sûr.
Ce n'est pas nouveau, donc ça ne vaut peut-être pas la peine d'être lu.
Peut-être avez-vous mesuré la vitesse d'exécution avec Python, mais ne l'avez pas considérée en profondeur.
J'ai utilisé par inadvertance time.time ()
pour mesurer le temps d'exécution.
C'était suffisant car je n'avais pas à me soucier de la précision, mais lorsque j'ai changé l'ordre d'exécution des fonctions qui devaient être indépendantes, le temps d'exécution a changé de manière significative.
La cause de ceci est inconnue, mais j'ai décidé de réexaminer la mesure du temps à la suite de cela.
(J'ai renoncé à essayer de découvrir pourquoi la fonction elle-même n'était pas pratique. Peut-être que le ramasse-miettes l'affecte.)
Windows 10 Pro 64bit Python 3.8.3
temps
Considérez uniquement le module time
, qui est la bibliothèque standard
Les fonctions qui peuvent être utilisées dans le module «time» pour mesurer le temps d'exécution sont les suivantes.
C'est monotonic = True
lorsqu'il est vérifié avec time.get_clock_info ()
.
En d'autres termes, il est garanti qu'il ne sera pas soustrait en raison de facteurs externes.
name | purpose | description | sleep | resolution |
---|---|---|---|---|
perf_counter() |
Mesure en temps réel | Valeur du compteur de performance | comprendre | haute |
process_time() |
Mesure du temps de fonctionnement réel dans le processus | Temps CPU total du système et de l'utilisateur pour le processus en cours | exclure | haute(Faible) |
thread_time() |
Mesurer le temps de fonctionnement réel dans un thread | Temps CPU total du système et de l'utilisateur pour le thread actuel | exclure | haute(Faible) |
monotonic() |
Mesure du temps écoulé du temps système | Temps écoulé après le démarrage du système | comprendre | Faible |
Je pense que ce que vous entendez par résolution "haute (basse)", c'est que les spécifications obtenues par time.get_clock_info ()
sont haute résolution, mais lorsque vous la déplacez réellement, elle est faible. Puisqu'il s'agit d'une résolution, c'est écrit comme ça.
Il peut être influencé par votre environnement de développement.
Une petite explication est la suivante.
perf_counter ()
est utilisé pour mesurer combien de temps réel s'est écoulé depuis l'exécution du programme.
Étant donné que le temps écoulé pendant le sommeil est également inclus, il est possible que l'heure prévue ne soit pas diffusée.
Cependant, il semble être le plus stable.
Il semble sûr de l'utiliser, comme être réglé sur le timer
par défaut avec timeit
etc.
process_time ()
ou thread_time ()
est utilisé pour savoir combien de temps un programme a été exécuté dans un processus (thread).
Je pense que beaucoup de gens, dont moi-même, veulent mesurer ce temps.
Cependant, la résolution réelle semble être inférieure aux spécifications.
J'ai vraiment envie de l'utiliser, mais j'hésite à l'utiliser.
De plus, dans le cas de Windows, j'utilise en fait C'GetProcessTimes () `, mais pour expliquer cela,
text
Note that this value can exceed the amount of real time elapsed (between lpCreationTime and lpExitTime) if the process executes across multiple CPU cores.
est ce qu'il lit. Cela ne semble pas très fiable.
monotonic ()
est utilisé pour connaître la disponibilité du système.
En d'autres termes, ce PC est utilisé pour savoir combien de jours se sont écoulés depuis sa mise en service.
Je ne pense pas que je l'utilise beaucoup.
time ()
obtient l'heure et n'est pas utilisé pour mesurer le temps d'exécution.
Le garbage collection semble affecter la vitesse d'exécution du programme.
Le timeit ()
décrit ci-dessous arrête le garbage collection comme comportement par défaut pour éviter ses effets.
De même, si vous souhaitez exclure l'effet du garbage collection de la mesure, vous devez arrêter le garbage collection.
La méthode consiste à écrire comme suit.
python
import gc
gc.disable() #Arrêtez
#Traitement des mesures
gc.enable() #Reprendre
Il est simple d'utiliser le module time
, mais il vous suffit de prendre le temps avant et après que vous vouliez le mesurer et le soustraire comme indiqué ci-dessous.
python
import time
import timeit
def stopwatchPrint(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
end = time.perf_counter()
print(f"{func.__name__}: {end - start:.3f} s.")
return result
return wrapper
@stopwatchPrint
def func1():
#Traiter quelque chose
return
def func2():
start = time.perf_counter()
#Traiter quelque chose
end = time.perf_counter()
print(f"Temps d'exécution: {end - start}"
return
timeit
Fondamentalement, il n'y a pas de problème si vous utilisez «time» comme ci-dessus.
Cependant, la bibliothèque standard fournit également un «timeit» pour mesurer la vitesse d'exécution.
La plupart d'entre eux appellent simplement time.perf_counter ()
, mais je vais l'expliquer brièvement.
Je ne parlerai pas de son utilisation à partir de la ligne de commande.
J'ai listé deux fonctions, mais je pense que vous ne devriez utiliser que timeit.repeat ()
.
python
import time
import timeit
timeit.timeit(stmt=func1, setup=func2, timer=time.time.perf_counter, number=1000000)
timeit.repeat(stmt=func1, setup=func2, timer=time.time.perf_counter, number=1000000, repeat=5)
timeit()
:
--stmt
: transmettez la fonction dont vous voulez mesurer le temps d'exécution ou la chaîne de caractères qui peut être évaluée comme une expression. S'il s'agit d'une chaîne, elle est évaluée par ʻeval () . --
setup: transmet une fonction qui effectue un prétraitement ou une chaîne de caractères pouvant être évaluée comme une expression. Le temps d'exécution de celui-ci n'est pas inclus dans la valeur mesurée. --
timer: Passez la fonction de minuterie utilisée pour la mesure. La valeur par défaut est «time.time.perf_counter». Vous pouvez passer
time.process_time etc. --
number: nombre d'exécutions. La valeur par défaut est «1000000». --
globals: spécifiez l'espace de noms. La valeur par défaut est «Aucun». Si vous voulez le changer, spécifiez
globals = globals ()ou
globals = locals (). --
repeat () : Une version répétitive de
time it. Il a ce qui suit en plus de l'argument de «timeit». --
répéter`: nombre de répétitions. Si "nombre = 100" et "répéter = 3", les 100 exécutions sont répétées 3 fois.En fait, il est utilisé comme suit.
result
est une liste de 3 longueurs écoulées lorsqu'un élément exécute longLongLongCat ()
100 fois.
python
def longLongLongCat(): #Fonction qui veut mesurer le temps
pass
result = timeit.repeat(longLongLongCat, ,number=100, repeat=3)
print(result)
timeit
La fonction d'exécution timeit
n'est pas conçue pour passer des arguments.
Il peut être nécessaire de l'exécuter en tant que chaîne, mais il est difficile de l'utiliser en standard.
Par conséquent, j'ai essayé diverses choses.
Il peut y avoir d'autres bonnes façons.
python
import math
import timeit
import functools
def func():
print("func")
def funcN(n):
print(f"funcN: {n}")
class Test():
def __init__(self, n=100, r=3):
self.number = n
self.repeat = r
def glo(self):
#print(globals())
#print(locals())
result = timeit.repeat("print(a, b)", number=self.number, repeat=self.repeat, globals=globals())
print(result)
def loc(self):
a = 33
b = 4
#print(globals())
#print(locals())
result = timeit.repeat("print(a, b)", number=self.number, repeat=self.repeat, globals=locals())
print(result)
def mix(self):
a = 33
b = 44
#print(globals())
#print(locals())
result = timeit.repeat("print(a , b)", number=self.number, repeat=self.repeat, globals={"a": 30, "b": 50})
print(result)
result = timeit.repeat("print(a , b)", number=self.number, repeat=self.repeat, globals={
"a": globals()["a"],
"b": locals()["b"]
})
print(result)
a = 2525
b = 2828
t = Test(1, 1)
t.glo()
t.loc()
t.mix()
timeit.repeat(func, number=1, repeat=1)
timeit.repeat(lambda: print(a, b), number=1, repeat=1)
n = 1129
timeit.repeat("funcN(n)", number=1, repeat=1, globals=globals())
timeit.repeat("funcN(n)", number=1, repeat=1, globals={"funcN": funcN, "n": 714})
g = globals()
g.update({"n": 1374})
timeit.repeat("funcN(n)", number=1, repeat=1, globals=g)
timeit.repeat(functools.partial(funcN, 184), number=1, repeat=1)
shell
2525 2828
[0.001136100000000001]
33 4
[0.026095200000000013]
30 50
[0.01867479999999999]
2525 44
[0.001263299999999995]
func
2525 2828
funcN: 1129
funcN: 714
funcN: 1374
funcN: 184
Informations dans votre propre environnement.
shell
>>> time.get_clock_info("monotonic")
namespace(adjustable=False, implementation='GetTickCount64()', monotonic=True, resolution=0.015625)
>>> time.get_clock_info("perf_counter")
namespace(adjustable=False, implementation='QueryPerformanceCounter()', monotonic=True, resolution=1e-07)
>>> time.get_clock_info("process_time")
namespace(adjustable=False, implementation='GetProcessTimes()', monotonic=True, resolution=1e-07)
>>> time.get_clock_info("thread_time")
namespace(adjustable=False, implementation='GetThreadTimes()', monotonic=True, resolution=1e-07)
>>> time.get_clock_info("time")
namespace(adjustable=True, implementation='GetSystemTimeAsFileTime()', monotonic=False, resolution=0.015625)
Recommended Posts