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

j'ai besoin de mesurer le temps 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 communs pour mesurer les temps d'exécution . Malheureusement, il a une interface terrible, en prenant un chaîne en entrée qu'il eval.

alors, dois-je utiliser ce module pour mesurer le temps avec précision, ou le temps suffira-t-il? Et quels sont les écueils qu'il désigne?

Merci

40
demandé sur hoju 2009-11-06 06:25:04

7 réponses

selon le Python documentation il a à voir avec la précision de la fonction de temps dans différents systèmes d'exploitation:

la fonction de minuterie par défaut est la plate-forme dépendre. Sur Windows, le temps.horloge() a une granularité microseconde mais temps.la granularité de time () est de 1/60ème de une seconde; sur Unix, le temps.clock() a 1 / 100ème d'une deuxième granularité et temps.time() est beaucoup plus précis. Sur soit, la plate-forme minuteur par défaut fonctions Mesurer l'Heure de l'horloge murale, pas le temps de calcul. Cela signifie que les autres processus tournant sur le même ordinateur peuvent interférer avec le calendrier ... Sur Unix, vous pouvez temps d'utilisation.horloge() pour mesurer le temps CPU.

pour tirer directement du code de timeit.py :

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 traite directement avec la mise en place du code d'exécution pour vous. Si vous prenez le temps, vous devez le faire vous-même. Ceci, bien sûr vous fait gagner du temps

timet's setup:

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

Edit, Python 3 seulement:

depuis Python 3.3 vous pouvez utiliser time.perf_counter() (calendrier à l'échelle du système) ou time.process_time() (timing pour l'ensemble du processus), exactement comme vous utilisiez time.clock() :

from time import process_time

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

la nouvelle fonction process_time n'inclut pas le temps écoulé dormir.

26
répondu Sean Vieira 2015-10-22 13:33:40

vous pouvez construire un contexte de temps (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()    
28
répondu Corey Porter 2009-11-06 04:05:56

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

8
répondu qid 2009-11-06 03:31:59

avez-vous examiné la fonctionnalité fournie profil ou cProfile?

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

cela fournit des informations beaucoup plus détaillées que l'impression juste le temps avant et après un appel de fonction. Peut-être en valeur un regard...

4
répondu AJ. 2009-11-06 03:50:22

j'ai été ennuyé aussi par l'interface terrible de timeit donc j'ai fait une bibliothèque pour cela, vérifier son trivial à utiliser


from pythonbenchmark import compare, measure
import time

a,b,c,d,e = 10,10,10,10,10
something = [a,b,c,d,e]

def myFunction(something):
    time.sleep(0.4)

def myOptimizedFunction(something):
    time.sleep(0.2)

# comparing test
compare(myFunction, myOptimizedFunction, 10, input)
# without input
compare(myFunction, myOptimizedFunction, 100)

https://github.com/Karlheinzniebuhr/pythonbenchmark

4
répondu karlpy 2017-04-11 01:34:24

la documentation mentionne également cette heure.clock() et l'heure.time () ont une résolution différente selon la plate-forme. Sur Unix, le temps.clock() mesure L'heure CPU par opposition à l'heure wall clock.

timeit désactive également la collecte des ordures lors de l'exécution des tests, ce qui n'est probablement pas ce que vous voulez pour le code de production.

je trouve ce temps.le temps() suffit pour la plupart des buts.

2
répondu Chris AtLee 2009-11-06 03:37:25

de Python 2.6 sur timeit n'est plus limité à la chaîne de saisie. Citant la documentation :

modifié dans la version 2.6: les paramètres stmt et setup peuvent maintenant aussi prendre des objets qui sont appelables sans arguments. Ceci intégrera les appels vers eux dans une fonction de timer qui sera ensuite exécutée par timeit(). Notez que les frais généraux de synchronisation sont un peu plus importants dans ce cas en raison des appels de fonction supplémentaires.

2
répondu jgosmann 2013-02-08 17:43:53