Mémo de mesure du temps d'exécution Python

Conclusion soudaine

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.

Lecteur supposé

Peut-être avez-vous mesuré la vitesse d'exécution avec Python, mais ne l'avez pas considérée en profondeur.

La raison de l'enquête

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.)

environnement

Windows 10 Pro 64bit Python 3.8.3

module temps

Considérez uniquement le module time, qui est la bibliothèque standard

Une fonction pour mesurer le temps d'exécution entre deux points

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.

Impact de la collecte des ordures

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

Comment utiliser

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

module 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)

Comment utiliser

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)

Passer des arguments à la fonction d'exécution 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)

Résultat de sortie

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 sur l'horloge

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

Mémo de mesure du temps d'exécution Python
Mesure du temps d'exécution avec Python avec
mesure du temps python
Temps d'exécution de la fonction (Python)
Sortie du temps d'exécution de python
Mesure du temps d'exécution
Mémo Python
mémo python
Mémo Python
mémo python
Mémo Python
Mémo Python
Mesurer le temps d'exécution de la fonction en Python
Python (de la première fois à l'exécution)
python> Traitement de la mesure du temps> time.time () --start_time
[Python] Mémo sur le dictionnaire
Premier Python
mesure du temps
Mémo d'exécution ALDA
mémo débutant python (9.2-10)
mémo débutant python (9.1)
★ Mémo ★ Python Iroha
Premier Python
[Python] Mémo EDA
Mémo opérateur Python 3
[Mon mémo] python
Mémo de métaclasse Python3
[Python] Mémo de fond de carte
Study memo 1_eclipse (python) téléchargement, exécution python, téléchargement OpenPyXL
Mémo débutant Python (2)
[Python] Mémo Numpy
[Python] Mémo de conversion entre les données temporelles et les données numériques
Comment mesurer le temps d'exécution avec Python Partie 1
mémo d'apprentissage progate Python (mis à jour de temps en temps)
Comment mesurer le temps d'exécution avec Python, partie 2
Python: analyse des séries chronologiques
Classe Python (mémo d'apprentissage Python ⑦)
installation de python openCV (mémo)
Mémo de visualisation par Python
Mémo du package de test Python
[Python] Mémo sur les fonctions
Question sur la série chronologique Python
mémo d'expression régulière python
Recherche de bisection (python2.7) mémo
[Mon mémo] python -v / python -V
Mémo de type Liste / Dictionnaire Python3
[Mémo] Tri de liste Python3
Astuces Python (mon mémo)
[Python] Mémo sur les erreurs
Mémo de script DynamoDB (Python)
Mémo de base Python - Partie 2
livre de recettes python Memo
Fonction de plancher de temps (Python)
Notes de commande de base Python
Mémo du didacticiel Python OpenCV
Mémo de grammaire de base Python
Mémo de l'API TensorFlow (Python)
liens de mémo utiles python
Mémo d'opération de décorateur Python