48 votes

mesurer avec précision le temps que prend une fonction python

J'ai besoin de mesurer le temps que prennent certaines parties de mon programme (pas pour le débogage mais comme une caractéristique de la sortie). La précision est importante car le temps total sera une fraction de seconde.

J'allais utiliser le module de temps quand je suis tombé sur timeit qui prétend éviter un certain nombre de pièges courants pour mesurer les temps d'exécution . Malheureusement, il a une interface horrible, prenant une chaîne en entrée qu'il évalue ensuite.

Alors, dois-je utiliser ce module pour mesurer le temps avec précision, ou le temps suffira-t-il ? Et quels sont les pièges auxquels il fait référence ?

Merci

4 votes

Précision ? En dessous de la seconde ? Comme la plupart des systèmes d'exploitation ont une programmation très souple, ces deux éléments ne vont pas ensemble. Il n'est pas possible de garantir une planification cohérente des événements à la seconde près. Vous aurez une variabilité énorme dans la façon dont votre processus est programmé. Qu'essayez-vous vraiment de faire ?

0 votes

Le module python "profile" ne fournirait-il pas le résultat dont vous avez besoin ?

36voto

Sean Vieira Points 47080

Selon le Python documentation Il s'agit de la précision de la fonction temporelle dans différents systèmes d'exploitation :

La fonction de minuterie par défaut est plateforme. Sous Windows, time.clock() a une granularité de l'ordre de la microseconde, mais mais la granularité de time.time() est de 1/60ème de seconde. seconde ; sous Unix, la granularité de time.clock() est de une granularité de 1/100ème de seconde et time.time() est beaucoup plus précis. Sur plate-forme, les fonctions de minuterie par par défaut mesurent le temps d'une horloge murale, et non le temps du processeur. Cela signifie que les autres processus en cours sur le même ordinateur peuvent interférer avec le chronométrage ... Sous Unix, vous pouvez utiliser time.clock() pour mesurer le temps CPU.

Pour tirer directement de timeit.py Le code de l'entreprise :

if sys.platform == "win32":
    # On Windows, the best timer is time.clock()
    default_timer = time.clock
else:
    # On most other platforms the best timer is time.time()
    default_timer = time.time

En outre, il s'occupe directement de configurer le code d'exécution pour vous. Si vous utilisez time vous devez le faire vous-même. Ceci, bien sûr vous fait gagner du temps

L'installation de Timeit :

def inner(_it, _timer):
    #Your setup code
    %(setup)s
    _t0 = _timer()
    for _i in _it:
        #The code you want to time
        %(stmt)s
    _t1 = _timer()
    return _t1 - _t0

Python 3 :

Depuis Python 3.3, vous pouvez utiliser time.perf_counter() (synchronisation à l'échelle du système) ou time.process_time() (synchronisation à l'échelle du processus), tout comme vous aviez l'habitude d'utiliser la fonction time.clock() :

from time import process_time

t = process_time()
#do some stuff
elapsed_time = process_time() - t

La nouvelle fonction process_time ne comprendra pas le temps écoulé pendant le sommeil.

Python 3.7+ :

Depuis Python 3.7, vous pouvez également utiliser process_time_ns() qui est similaire à process_time() mais renvoie le temps en nanosecondes.

3 votes

timeit.default_timer es time.perf_counter sur Python 3.3+, c'est-à-dire que vous pourriez utiliser default_timer sur toutes les versions.

0 votes

Pour l'enregistrement si vous utilisez ceci dans un script j'ai dû faire import time au lieu de import time.process_time ou from time import process_time sur 3.4, ou peut-être que je fais quelque chose de mal ;)

0 votes

@matrixanomaly Vous n'avez pas tort du tout. Cette réponse explique (un peu) pourquoi : vous devez préciser si time fait référence au module, ou à la fonction qu'il contient.

29voto

Corey Porter Points 1016

Vous pouvez construire un contexte de synchronisation (voir PEP 343 ) pour mesurer des blocs de code assez facilement.

from __future__ import with_statement
import time

class Timer(object):
    def __enter__(self):
        self.__start = time.time()

    def __exit__(self, type, value, traceback):
        # Error handling here
        self.__finish = time.time()

    def duration_in_seconds(self):
        return self.__finish - self.__start

timer = Timer()

with timer:
    # Whatever you want to measure goes here
    time.sleep(2)

print timer.duration_in_seconds()

0 votes

Cela semble assez simple pour des mesures transversales. Mais pour les opérations atomiques à grain fin comme celles décrites dans les questions (où les millisecondes comptent), je ne suis pas sûr.

8voto

qid Points 1289

Le module timeit semble avoir été conçu pour tester les performances des algorithmes, plutôt que pour surveiller simplement une application. Votre meilleure option est probablement d'utiliser le module time, d'appeler time.time() au début et à la fin du segment qui vous intéresse, et soustrayez les deux nombres. Sachez que le nombre que vous obtenez peut avoir beaucoup plus de décimales que la résolution réelle de la minuterie du système.

0 votes

Oui, c'est ce à quoi j'ai pensé à l'origine, avant de voir le module Timeit.

4voto

AJ. Points 12912

Avez-vous examiné la fonctionnalité fournie par le profil ou le cProfile ?

http://docs.python.org/library/profile.html

Cela fournit des informations beaucoup plus détaillées que la simple impression du temps avant et après un appel de fonction. Cela vaut peut-être le coup de jeter un coup d'oeil...

0 votes

@CruiZen - bien sûr, cette question/réponse date d'il y a un an et demi :)

3voto

Chris AtLee Points 3656

La documentation mentionne également que time.clock() et time.time() ont une résolution différente selon la plateforme. Sous Unix, time.clock() mesure le temps du processeur par opposition au temps de l'horloge murale.

timeit désactive également le garbage collection lors de l'exécution des tests, ce qui n'est probablement pas ce que vous souhaitez pour le code de production.

Je trouve que time.time() suffit dans la plupart des cas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X