Mesurer le temps écoulé en Python?

ce que je veux c'est commencer à compter le temps quelque part dans mon code et ensuite obtenir le temps passé, pour mesurer le temps qu'il a fallu pour exécuter peu de fonction. Je pense que j'utilise mal le module timeit, mais les docs sont juste déroutants pour moi.

import timeit

start = timeit.timeit()
print "hello"
end = timeit.timeit()
print end - start
680
demandé sur Franck Dernoncourt 2011-09-10 13:21:02
la source

20 ответов

si vous voulez simplement mesurer le temps d'horloge mural écoulé entre deux points, vous pouvez utiliser time.time() :

import time

start = time.time()
print("hello")
end = time.time()
print(end - start)

donne le temps d'exécution en secondes.

une autre option puisque 3.3 pourrait être d'utiliser perf_counter ou process_time , selon vos besoins. Avant 3.3, il était recommandé d'utiliser time.clock (merci Ambre ). Toutefois, il est actuellement déprécié:

sur Unix, renvoie le temps du processeur en cours sous la forme d'un nombre à virgule flottante exprimée en secondes. La précision, et en fait la définition même de la notion de "temps processeur", ne dépend que de la fonction C du même nom.

sur Windows, Cette fonction renvoie les secondes d'horloge murales écoulées depuis le premier appel à cette fonction, comme un nombre à virgule flottante, basé sur la Fonction Win32 QueryPerformanceCounter() . La résolution est typiquement mieux que la microseconde.

déprécié depuis la version 3.3 : le comportement de cette fonction dépend sur la plate-forme: utiliser perf_counter() ou process_time() à la place , selon vos besoins, à avoir un comportement défini.

885
répondu NPE 2018-06-21 10:38:03
la source

utiliser timeit.default_timer au lieu de timeit.timeit . Le premier fournit la meilleure horloge disponible sur votre plate-forme et la version de Python automatiquement:

from timeit import default_timer as timer

start = timer()
# ...
end = timer()
print(end - start) # Time in seconds, e.g. 5.38091952400282

timeit.default_timer est assigné au temps.time() ou de temps.horloge() selon OS. Sur Python 3.3+ default_timer est time.perf_counter() sur toutes les plateformes. Voir Python-time.clock() en fonction du temps.time() - précision?

voir aussi:

307
répondu jfs 2018-09-15 14:35:53
la source

Python 3 seulement:

depuis le temps.clock () est déprécié à partir de Python 3.3 , vous voudrez utiliser time.perf_counter() pour le chronométrage à l'échelle du système, ou time.process_time() pour le chronométrage à l'échelle du processus, juste la façon dont vous avez utilisé time.clock() :

import time

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

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

89
répondu Pierre Prinetti 2016-11-11 16:03:41
la source

étant donné une fonction que vous aimeriez chronométrer,

test.py:

def foo(): 
    # print "hello"   
    return "hello"

la façon la plus simple d'utiliser timeit est de l'appeler depuis la ligne de commande:

% python -mtimeit -s'import test' 'test.foo()'
1000000 loops, best of 3: 0.254 usec per loop

N'essayez pas d'utiliser time.time ou time.clock (naïvement) pour comparer la vitesse de fonctions. Ils peuvent donner des résultats trompeurs .

PS. Ne mettez pas d'instructions d'impression dans une fonction que vous souhaitez chronométrer; dans le cas contraire, le temps mesuré dépendra de la Vitesse du terminal .

69
répondu unutbu 2017-05-23 15:34:54
la source

je préfère ça. timeit doc est beaucoup trop confus.

from datetime import datetime 

start_time = datetime.now() 

# INSERT YOUR CODE 

time_elapsed = datetime.now() - start_time 

print('Time elapsed (hh:mm:ss.ms) {}'.format(time_elapsed))

Note, qu'il n'y a pas de formatage en cours ici, je viens d'écrire hh:mm:ss dans l'imprimé pour qu'on puisse interpréter time_elapsed

41
répondu user1761806 2018-01-01 10:46:24
la source

c'est amusant de faire cela avec un gestionnaire de contexte qui se souvient automatiquement de l'Heure de début à l'entrée d'un bloc with , puis gèle l'Heure de fin sur la sortie du bloc. Avec un peu de ruse, vous pouvez même obtenir un décompte du temps écoulé à l'intérieur du bloc à partir de la même fonction de gestionnaire de contexte.

la bibliothèque principale n'a pas ceci (mais devrait probablement le faire). Une fois en place, vous pouvez faire des choses comme:

with elapsed_timer() as elapsed:
    # some lengthy code
    print( "midpoint at %.2f seconds" % elapsed() )  # time so far
    # other lengthy code

print( "all done at %.2f seconds" % elapsed() )

voilà contextmanager code suffisant pour faire l'affaire:

from contextlib import contextmanager
from timeit import default_timer

@contextmanager
def elapsed_timer():
    start = default_timer()
    elapser = lambda: default_timer() - start
    yield lambda: elapser()
    end = default_timer()
    elapser = lambda: end-start

et un code de démonstration exécutable:

import time

with elapsed_timer() as elapsed:
    time.sleep(1)
    print(elapsed())
    time.sleep(2)
    print(elapsed())
    time.sleep(3)

notez que par conception de cette fonction, la valeur de retour de elapsed() est gelée à la sortie du bloc, et d'autres appels reviennent de la même durée (d'environ 6 secondes dans cet exemple de jouet).

35
répondu gojomo 2015-11-29 00:29:58
la source

L'utilisation de time.time pour mesurer l'exécution vous donne le temps d'exécution total de vos commandes, y compris le temps d'exécution passé par d'autres processus sur votre ordinateur. C'est le temps que l'utilisateur remarque, mais ce n'est pas bon si vous voulez comparer différents morceaux de code / algorithmes / fonctions / ...

plus d'information sur timeit :

si vous voulez un aperçu plus profond dans le profilage:

Update : j'ai utilisé http://pythonhosted.org/line_profiler / beaucoup au cours de la dernière année et le trouver très utile et recommande de l'utiliser à la place de pythons profile module.

23
répondu rocksportrocker 2017-05-23 14:47:29
la source

Voici une minuscule classe de minuterie qui renvoie" HH:mm: ss "string:

class Timer:
  def __init__(self):
    self.start = time.time()

  def restart(self):
    self.start = time.time()

  def get_time_hhmmss(self):
    end = time.time()
    m, s = divmod(end - self.start, 60)
    h, m = divmod(m, 60)
    time_str = "%02d:%02d:%02d" % (h, m, s)
    return time_str

Utilisation:

# Start timer
my_timer = Timer()

# ... do something

# Get time string:
time_hhmmss = my_timer.get_time_hhmmss()
print("Time elapsed: %s" % time_hhmmss )

# ... use the timer again
my_timer.restart()

# ... do something

# Get time:
time_hhmmss = my_timer.get_time_hhmmss()

# ... etc
17
répondu Danijel 2017-04-27 09:35:07
la source

les modules python cProfile et pstats offrent un grand support pour mesurer le temps écoulé dans certaines fonctions sans avoir à ajouter de code autour des fonctions existantes.

par exemple si vous avez un script python timeFunctions.py:

import time

def hello():
    print "Hello :)"
    time.sleep(0.1)

def thankyou():
    print "Thank you!"
    time.sleep(0.05)

for idx in range(10):
    hello()

for idx in range(100):
    thankyou()

pour exécuter le profileur et générer des statistiques pour le fichier que vous pouvez simplement exécuter:

python -m cProfile -o timeStats.profile timeFunctions.py

ce que cela fait est d'utiliser le module cProfile pour profiler toutes les fonctions timeFunctions.py et la collecte des statistiques dans les timeStats.le fichier de profil. Notez que nous n'avons pas eu à ajouter de code au module existant (timeFunctions.py) et cela peut être fait avec n'importe quel module.

une fois que vous avez le fichier stats, vous pouvez exécuter le module pstats comme suit:

python -m pstats timeStats.profile

cela exécute le navigateur statistique interactif qui vous donne beaucoup de fonctionnalité agréable. Pour votre cas d'utilisation particulier, vous pouvez simplement consulter les statistiques de votre fonction. Dans notre exemple, la vérification des statistiques pour les deux fonctions nous montre ce qui suit:

Welcome to the profile statistics browser.
timeStats.profile% stats hello
<timestamp>    timeStats.profile

         224 function calls in 6.014 seconds

   Random listing order was used
   List reduced from 6 to 1 due to restriction <'hello'>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       10    0.000    0.000    1.001    0.100 timeFunctions.py:3(hello)

timeStats.profile% stats thankyou
<timestamp>    timeStats.profile

         224 function calls in 6.014 seconds

   Random listing order was used
   List reduced from 6 to 1 due to restriction <'thankyou'>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      100    0.002    0.000    5.012    0.050 timeFunctions.py:7(thankyou)

l'exemple fictif ne fait pas grand-chose, mais vous donne une idée de ce qui peut être fait. La meilleure partie de cette approche est que je n'ai pas à éditer l'un de mes codes existants pour obtenir ces numéros et évidemment aider avec le profilage.

14
répondu sanchitarora 2013-12-27 02:03:36
la source

(avec Ipython seulement) vous pouvez utiliser %timeit pour mesurer le temps de traitement moyen:

def foo():
    print "hello"

et ensuite:

%timeit foo()

le résultat est quelque chose comme:

10000 loops, best of 3: 27 µs per loop
12
répondu Eyal Ch 2016-12-15 17:24:22
la source

voici un autre gestionnaire de contexte pour le code de synchronisation -

Utilisation:

from benchmark import benchmark

with benchmark("Test 1+1"):
    1+1
=>
Test 1+1 : 1.41e-06 seconds

ou, si vous avez besoin de la valeur temporelle

with benchmark("Test 1+1") as b:
    1+1
print(b.time)
=>
Test 1+1 : 7.05e-07 seconds
7.05233786763e-07

benchmark.py :

from timeit import default_timer as timer

class benchmark(object):

    def __init__(self, msg, fmt="%0.3g"):
        self.msg = msg
        self.fmt = fmt

    def __enter__(self):
        self.start = timer()
        return self

    def __exit__(self, *args):
        t = timer() - self.start
        print(("%s : " + self.fmt + " seconds") % (self.msg, t))
        self.time = t

adapté de http://dabeaz.blogspot.fr/2010/02/context-manager-for-timing-benchmarks.html

12
répondu Brian Burns 2016-12-31 16:03:03
la source

utiliser le module profileur. Il donne un profil détaillé.

import profile
profile.run('main()')

, il renvoie à quelque chose comme:

          5 function calls in 0.047 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.000    0.000 :0(exec)
        1    0.047    0.047    0.047    0.047 :0(setprofile)
        1    0.000    0.000    0.000    0.000 <string>:1(<module>)
        0    0.000             0.000          profile:0(profiler)
        1    0.000    0.000    0.047    0.047 profile:0(main())
        1    0.000    0.000    0.000    0.000 two_sum.py:2(twoSum)

je l'ai trouvé très instructif.

12
répondu Leonid Ganeline 2017-07-19 02:19:03
la source

sur python3:

from time import sleep, perf_counter as pc
t0 = pc()
sleep(1)
print(pc()-t0)

élégant et court.

8
répondu DmitrySemenov 2016-01-15 10:15:25
la source

une sorte de super réponse plus tard, mais peut-être que ça sert un but pour quelqu'un. C'est une façon de le faire que je trouve super propre.

import time

def timed(fun, *args):
    s = time.time()
    r = fun(*args)
    print('{} execution took {} seconds.'.format(fun.__name__, time.time()-s))
    return(r)

timed(print, "Hello")

gardez à l'esprit que" print " est une fonction en Python 3 et non Python 2.7. Cependant, il fonctionne avec toute autre fonction. Acclamations!

7
répondu Andreas Herman 2017-08-14 17:33:44
la source

une autre façon d'utiliser timeit :

from timeit import timeit

def func():
    return 1 + 1

time = timeit(func, number=1)
print(time)
5
répondu raacer 2016-12-15 15:39:22
la source

Nous pouvons également convertir le temps en lisible temps.

import time, datetime

start = time.clock()

def num_multi1(max):
    result = 0
    for num in range(0, 1000):
        if (num % 3 == 0 or num % 5 == 0):
            result += num

    print "Sum is %d " % result

num_multi1(1000)

end = time.clock()
value = end - start
timestamp = datetime.datetime.fromtimestamp(value)
print timestamp.strftime('%Y-%m-%d %H:%M:%S')
5
répondu Kamlesh Verma 2017-02-17 01:01:23
la source

j'ai fait une bibliothèque pour cela, si vous voulez mesurer une fonction vous pouvez juste le faire comme ceci


from pythonbenchmark import compare, measure
import time

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

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

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

myFunction(input)
myOptimizedFunction(input)

https://github.com/Karlheinzniebuhr/pythonbenchmark

4
répondu karlpy 2015-05-04 20:02:23
la source

vous pouvez utiliser timeit.

voici un exemple sur la façon de tester naive_func qui prend le paramètre en utilisant Python REPL:

>>> import timeit                                                                                         

>>> def naive_func(x):                                                                                    
...     a = 0                                                                                             
...     for i in range(a):                                                                                
...         a += i                                                                                        
...     return a                                                                                          

>>> def wrapper(func, *args, **kwargs):                                                                   
...     def wrapper():                                                                                    
...         return func(*args, **kwargs)                                                                  
...     return wrapper                                                                                    

>>> wrapped = wrapper(naive_func, 1_000)                                                                  

>>> timeit.timeit(wrapped, number=1_000_000)                                                              
0.4458435332577161  

vous n'avez pas besoin de fonction wrapper si la fonction n'a pas de paramètres.

3
répondu Vlad Bezden 2017-06-19 20:52:52
la source

Voici mes conclusions après avoir traversé beaucoup de bonnes réponses ici, ainsi que quelques autres articles.

tout D'abord, vous voulez toujours utiliser timeit et non time.time (et dans de nombreux cas, perf counter APIs) parce que

  1. timeit sélectionne le meilleur minuteur disponible sur votre version OS et Python.
  2. timeit empêche la collecte des ordures, mais ce n'est pas quelque chose que vous voulez ou que vous ne voulez pas.

maintenant, le problème est que timeit n'est pas si simple à utiliser parce qu'il a besoin de configuration et les choses deviennent moches quand vous avez tas d'importations. Idéalement, vous voulez juste un décorateur ou utiliser with bloc et mesurer le temps. Malheureusement, il n'y a rien intégré disponible pour cela, donc j'ai créé ci-dessous petit module utilitaire.

Module De Minuterie

# utils.py
from functools import wraps
import gc
import timeit

def MeasureTime(f):
    @wraps(f)
    def _wrapper(*args, **kwargs):
        gcold = gc.isenabled()
        gc.disable()
        start_time = timeit.default_timer()
        try:
            result = f(*args, **kwargs)
        finally:
            elapsed = timeit.default_timer() - start_time
            if gcold:
                gc.enable()
            print('Function "{}": {}s'.format(f.__name__, elapsed))
        return result
    return _wrapper

class MeasureBlockTime:
    def __init__(self,name="(block)", no_print = False, disable_gc = True):
        self.name = name
        self.no_print = no_print
        self.disable_gc = disable_gc
    def __enter__(self):
        if self.disable_gc:
            self.gcold = gc.isenabled()
            gc.disable()
        self.start_time = timeit.default_timer()
    def __exit__(self,ty,val,tb):
        self.elapsed = timeit.default_timer() - self.start_time
        if self.disable_gc and self.gcold:
            gc.enable()
        if not self.no_print:
            print('Function "{}": {}s'.format(self.name, self.elapsed))
        return False #re-raise any exceptions

Comment faire Fonctions Du Temps

Maintenant vous pouvez chronométrer n'importe quelle fonction juste en mettant un décorateur en face de lui:

import utils

@utils.MeasureTime
def MyBigFunc():
    #do something time consuming
    for i in range(10000):
        print(i)

Comment le Temps des Blocs de Code

si vous voulez chronométrer la portion de code, mettez-la à l'intérieur du bloc with :

import utils

#somewhere in my code

with utils.MeasureBlockTime("MyBlock"):
    #do something time consuming
    for i in range(10000):
        print(i)

# rest of my code

avantages

il y a plusieurs versions à demi-fond flottant autour de donc je tiens à souligner quelques points saillants:

  1. utiliser timer de timeit au lieu de temps.le temps pour les raisons décrites plus haut.
  2. Désactiver GC pendant le chronométrage.
  3. Décorateur accepte les fonctions nommé ou non params.
  4. possibilité de désactiver l'impression en bloc (utiliser with utils.MeasureBlockTime() as t puis t.elapsed ).
  5. capacité de garder le CA activé pour la synchronisation des blocs.
1
répondu ShitalShah 2018-09-12 09:24:11
la source

la seule façon dont je peux penser est d'utiliser time.time() .

import time
start = time.time()
sleep(5) #just to give it some delay to show it working
finish = time.time()
elapsed = finish - start
print(elapsed)

Espère que cela va aider.

0
répondu Trooper Z 2018-06-17 17:53:00
la source

Autres questions sur python performance measure timeit