Si vous voulez vraiment l'équivalent direct, appelez simplement tic = time.time()et toc = time.time(), alors print toc-tic, 'sec Elapsed'comme les gens l'ont dit ci-dessous, cependant, timeitc'est plus robuste.
Joe Kington
Il me semble obtenir de meilleurs résultats en utilisant l'approche de @ JoeKington en conjonction avec timeit.default_timer (), comme ceci par exemple:, tic = timeit.default_timer(); (U,S,V) = np.linalg.svd(A); toc = timeit.default_timer()alors print toc-tic.
littleO
1
La bibliothèque pytictoc semble la plus conveinente, la syntaxe est même légèrement plus claire que ttictoc ci-dessous. pypi.org/project/pytictoc
FlorianH
Réponses:
174
Mis à part timeitce que ThiefMaster a mentionné, un moyen simple de le faire est juste (après l'importation time):
t = time.time()# do stuff
elapsed = time.time()- t
@eat: Je suis respectueusement en désaccord. Les gens utilisent depuis toujours la timecommande unix pour mesurer les temps d'exécution des programmes, et cette méthode reproduit cela dans le code Python. Je ne vois rien de mal à cela, tant que c'est le bon outil pour le travail. timeitn'est pas toujours cela, et un profileur est une solution beaucoup plus lourde pour la plupart des besoins
Eli Bendersky
4
Pour la dernière ligne, je suggérerais print 'Elapsed: %.2f seconds % (time.time() - self.tstart)'. C'est difficile à comprendre sans le% .2f. Merci pour cette excellente idée.
Can Kavaklıoğlu
4
Cela semble très pratique à première vue, mais en pratique, il faut indenter le bloc de code que l'on veut chronométrer, ce qui peut être assez gênant selon la longueur du bloc de code et l'éditeur de choix. Encore une solution élégante, qui se comporte correctement en cas d'utilisation imbriquée.
Stefan
1
Je pense que tu veux elapsed = t - time.time(), au lieu de elapsed = time.time() - t. Dans ce dernier écoulé sera négatif. J'ai suggéré ce changement en tant que modification.
rysqui
3
@rysqui - L' heure actuelle n'est-elle pas toujours un nombre plus grand qu'une heure précédente ? Je pense que elapsed = time.time() - tc'est la forme qui donne toujours une valeur positive.
Scott Smith
32
J'ai eu la même question lorsque j'ai migré vers python depuis Matlab. Avec l'aide de ce fil, j'ai pu construire un analogue exact du Matlab tic()et des toc()fonctions. Insérez simplement le code suivant en haut de votre script.
import time
defTicTocGenerator():# Generator that returns time differences
ti =0# initial time
tf = time.time()# final timewhileTrue:
ti = tf
tf = time.time()yield tf-ti # returns the time differenceTicToc=TicTocGenerator()# create an instance of the TicTocGen generator# This will be the main function through which we define both tic() and toc()def toc(tempBool=True):# Prints the time difference yielded by generator instance TicToc
tempTimeInterval =next(TicToc)if tempBool:print("Elapsed time: %f seconds.\n"%tempTimeInterval )def tic():# Records a time in TicToc, marks the beginning of a time interval
toc(False)
C'est tout! Nous sommes maintenant prêts à être pleinement utilisés tic()et toc()comme dans Matlab. Par exemple
En fait, c'est plus polyvalent que les fonctions Matlab intégrées. Ici, vous pouvez créer une autre instance de TicTocGeneratorpour suivre plusieurs opérations ou simplement pour chronométrer les choses différemment. Par exemple, tout en chronométrant un script, nous pouvons désormais chronométrer chaque élément du script séparément, ainsi que le script entier. (Je vais donner un exemple concret)
TicToc2=TicTocGenerator()# create another instance of the TicTocGen generatordef toc2(tempBool=True):# Prints the time difference yielded by generator instance TicToc2
tempTimeInterval =next(TicToc2)if tempBool:print("Elapsed time 2: %f seconds.\n"%tempTimeInterval )def tic2():# Records a time in TicToc2, marks the beginning of a time interval
toc2(False)
Vous devriez maintenant pouvoir chronométrer deux choses distinctes: Dans l'exemple suivant, nous chronométrons le script total et les parties d'un script séparément.
En fait, vous n'avez même pas besoin de l'utiliser à tic()chaque fois. Si vous avez une série de commandes que vous souhaitez chronométrer, vous pouvez écrire
Le meilleur analogue absolu de tic et toc serait de simplement les définir en python.
def tic():#Homemade version of matlab tic and toc functionsimport time
global startTime_for_tictoc
startTime_for_tictoc = time.time()def toc():import time
if'startTime_for_tictoc'in globals():print"Elapsed time is "+ str(time.time()- startTime_for_tictoc)+" seconds."else:print"Toc: start time not set"
Cela ne fonctionnera pas correctement dans le cas d'une utilisation imbriquée de ticet toc, que Matlab prend en charge. Un peu plus de sophistication serait nécessaire.
Stefan
2
J'ai implémenté des fonctions similaires dans mon propre code lorsque j'avais besoin d'un timing de base. Je supprimerais cependant l' import timeextérieur des deux fonctions, car cela peut prendre un certain temps.
Bas Swinckels
Si vous insistez pour utiliser cette technique et que vous en avez besoin pour gérer les tic / toc imbriqués, créez une liste globale et laissez-la ticpousser et tocsortez d'elle.
Ahmed Fasih
1
J'ai aussi lu ailleurs que timeit.default_timer()c'est mieux que time.time()parce que cela time.clock()pourrait être plus approprié selon le système d'exploitation
Miguel
@AhmedFasih C'est ce que fait ma réponse, même si d'autres choses pourraient être améliorées.
antonimmo le
15
Habituellement, IPython de %time, %timeit, %prunet %lprun(si l' on a line_profilerinstallé) satisfaire mes besoins de profilage très bien. Cependant, un cas d'utilisation pour une tic-tocfonctionnalité similaire est apparu lorsque j'ai essayé de profiler des calculs qui étaient pilotés de manière interactive, c'est-à-dire par le mouvement de la souris de l'utilisateur dans une interface graphique. J'avais l'impression que spammer les tics et tocs dans les sources tout en testant de manière interactive serait le moyen le plus rapide de révéler les goulots d'étranglement. Je suis allé avec la Timerclasse d' Eli Bendersky , mais je n'étais pas entièrement satisfait, car cela m'obligeait à changer l'indentation de mon code, ce qui peut être gênant pour certains éditeurs et confond le système de contrôle de version. De plus, il peut être nécessaire de mesurer le temps entre les points dans différentes fonctions, ce qui ne fonctionnerait pas avec lewithdéclaration. Après avoir essayé beaucoup d'intelligence Python, voici la solution simple que j'ai trouvée fonctionnant le mieux:
from time import time
_tstart_stack =[]def tic():
_tstart_stack.append(time())def toc(fmt="Elapsed: %s s"):print fmt %(time()- _tstart_stack.pop())
Comme cela fonctionne en poussant les heures de départ sur une pile, cela fonctionnera correctement pour plusieurs niveaux de tics et de tocs. Cela permet également de changer la chaîne de format de l' tocinstruction pour afficher des informations supplémentaires, ce que j'ai aimé sur la Timerclasse d'Eli .
Pour une raison quelconque, je me suis préoccupé de la surcharge d'une implémentation pure Python, alors j'ai également testé un module d'extension C:
C'est pour MacOSX, et j'ai omis le code pour vérifier s'il lvlest hors limites par souci de concision. Bien que tictoc.res()donne une résolution d'environ 50 nanosecondes sur mon système, j'ai trouvé que l'instabilité de la mesure de toute instruction Python se situe facilement dans la plage de la microseconde (et bien plus encore lorsqu'elle est utilisée à partir d'IPython). À ce stade, la surcharge de l'implémentation Python devient négligeable, de sorte qu'elle peut être utilisée avec la même confiance que l'implémentation C.
J'ai trouvé que l'utilité de l' tic-tocapproche -approach est pratiquement limitée aux blocs de code qui prennent plus de 10 microsecondes à exécuter. En dessous, des stratégies de calcul de la moyenne comme dans timeitsont nécessaires pour obtenir une mesure fidèle.
Je viens de créer un module [tictoc.py] pour réaliser des tic tocs imbriqués, ce que fait Matlab.
from time import time
tics =[]def tic():
tics.append(time())def toc():if len(tics)==0:returnNoneelse:return time()-tics.pop()
Et cela fonctionne de cette façon:
from tictoc import tic, toc
# This keeps track of the whole process
tic()# Timing a small portion of code (maybe a loop)
tic()# -- Nested code here --# End
toc()# This returns the elapse time (in seconds) since the last invocation of tic()
toc()# This does the same for the first tic()
Je dois vous avertir que cela pourrait ne pas se comporter comme vous le souhaitez lorsqu'il est utilisé simultanément par plus d'un module, car les modules (AFAIK) se comportent comme des singletons.
antonimmo le
3
Jetez un œil au timeitmodule. Ce n'est pas vraiment équivalent mais si le code que vous voulez chronométrer est à l'intérieur d'une fonction, vous pouvez facilement l'utiliser.
Oui, timeitc'est mieux pour les benchmarks. Il n'est même pas nécessaire que ce soit une fonction unique, vous pouvez passer des instructions abritement complexes.
10
Eh bien, passer du code qui n'est pas un appel de fonction extrêmement simple sous forme de chaîne est très moche.
ThiefMaster
2
pip install easy-tictoc
Dans le code:
from tictoc import tic, toc
tic()#Some code
toc()
Avertissement: je suis l'auteur de cette bibliothèque.
Cela peut également être fait à l'aide d'un wrapper. Façon très générale de garder le temps.
L'encapsuleur de cet exemple de code encapsule n'importe quelle fonction et imprime le temps nécessaire pour exécuter la fonction:
def timethis(f):import time
def wrapped(*args,**kwargs):
start = time.time()
r = f(*args,**kwargs)print"Executing {0} took {1} seconds".format(f.func_name, time.time()-start)return r
return wrapped
@timethisdef thistakestime():for x in range(10000000):pass
thistakestime()
La fonction wrapper, timthis est appelée un décorateur. Une explication un peu plus détaillée, ici: medium.com/pythonhive
Mircea
1
J'ai changé un peu la réponse de @Eli Bendersky pour utiliser le ctor __init__()et le dtor __del__()pour faire le timing, afin qu'il puisse être utilisé plus facilement sans indenter le code d'origine:
Un problème avec cette implémentation est le fait qu'elle timern'est pas supprimée après le dernier appel, si un autre code suit après la forboucle. Pour obtenir la dernière valeur du timer, il faut supprimer ou écraser timerla forboucle après la boucle, par exemple via timer = None.
bastelflp
1
@bastelflp Je viens de réaliser que j'ai mal compris ce que vous vouliez dire ... Votre suggestion a été incorporée dans le code maintenant. Merci.
Tout comme Eli, il peut être utilisé comme gestionnaire de contexte:
import time
withTimer('Count'):for i in range(0,10_000_000):pass
Production:
[Count]Elapsed:0.27 seconds
Je l'ai également mis à jour pour imprimer les unités de temps rapportées (secondes) et couper le nombre de chiffres comme suggéré par Can, et avec la possibilité d'ajouter également à un fichier journal. Vous devez importer datetime pour utiliser la fonction de journalisation:
import time
import datetime
withTimer('Count','log.txt'):for i in range(0,10_000_000):pass
tic = time.time()
ettoc = time.time()
, alorsprint toc-tic, 'sec Elapsed'
comme les gens l'ont dit ci-dessous, cependant,timeit
c'est plus robuste.tic = timeit.default_timer(); (U,S,V) = np.linalg.svd(A); toc = timeit.default_timer()
alorsprint toc-tic
.Réponses:
Mis à part
timeit
ce que ThiefMaster a mentionné, un moyen simple de le faire est juste (après l'importationtime
):J'ai une classe d'aide que j'aime utiliser:
Il peut être utilisé comme gestionnaire de contexte:
Parfois, je trouve cette technique plus pratique que
timeit
- tout dépend de ce que vous voulez mesurer.la source
time
commande unix pour mesurer les temps d'exécution des programmes, et cette méthode reproduit cela dans le code Python. Je ne vois rien de mal à cela, tant que c'est le bon outil pour le travail.timeit
n'est pas toujours cela, et un profileur est une solution beaucoup plus lourde pour la plupart des besoinsprint 'Elapsed: %.2f seconds % (time.time() - self.tstart)'
. C'est difficile à comprendre sans le% .2f. Merci pour cette excellente idée.elapsed = t - time.time()
, au lieu deelapsed = time.time() - t
. Dans ce dernier écoulé sera négatif. J'ai suggéré ce changement en tant que modification.elapsed = time.time() - t
c'est la forme qui donne toujours une valeur positive.J'ai eu la même question lorsque j'ai migré vers python depuis Matlab. Avec l'aide de ce fil, j'ai pu construire un analogue exact du Matlab
tic()
et destoc()
fonctions. Insérez simplement le code suivant en haut de votre script.C'est tout! Nous sommes maintenant prêts à être pleinement utilisés
tic()
ettoc()
comme dans Matlab. Par exempleEn fait, c'est plus polyvalent que les fonctions Matlab intégrées. Ici, vous pouvez créer une autre instance de
TicTocGenerator
pour suivre plusieurs opérations ou simplement pour chronométrer les choses différemment. Par exemple, tout en chronométrant un script, nous pouvons désormais chronométrer chaque élément du script séparément, ainsi que le script entier. (Je vais donner un exemple concret)Vous devriez maintenant pouvoir chronométrer deux choses distinctes: Dans l'exemple suivant, nous chronométrons le script total et les parties d'un script séparément.
En fait, vous n'avez même pas besoin de l'utiliser à
tic()
chaque fois. Si vous avez une série de commandes que vous souhaitez chronométrer, vous pouvez écrireJ'espère que cela est utile.
la source
Le meilleur analogue absolu de tic et toc serait de simplement les définir en python.
Ensuite, vous pouvez les utiliser comme:
la source
tic
ettoc
, que Matlab prend en charge. Un peu plus de sophistication serait nécessaire.import time
extérieur des deux fonctions, car cela peut prendre un certain temps.tic
pousser ettoc
sortez d'elle.timeit.default_timer()
c'est mieux quetime.time()
parce que celatime.clock()
pourrait être plus approprié selon le système d'exploitationHabituellement, IPython de
%time
,%timeit
,%prun
et%lprun
(si l' on aline_profiler
installé) satisfaire mes besoins de profilage très bien. Cependant, un cas d'utilisation pour unetic-toc
fonctionnalité similaire est apparu lorsque j'ai essayé de profiler des calculs qui étaient pilotés de manière interactive, c'est-à-dire par le mouvement de la souris de l'utilisateur dans une interface graphique. J'avais l'impression que spammer lestic
s ettoc
s dans les sources tout en testant de manière interactive serait le moyen le plus rapide de révéler les goulots d'étranglement. Je suis allé avec laTimer
classe d' Eli Bendersky , mais je n'étais pas entièrement satisfait, car cela m'obligeait à changer l'indentation de mon code, ce qui peut être gênant pour certains éditeurs et confond le système de contrôle de version. De plus, il peut être nécessaire de mesurer le temps entre les points dans différentes fonctions, ce qui ne fonctionnerait pas avec lewith
déclaration. Après avoir essayé beaucoup d'intelligence Python, voici la solution simple que j'ai trouvée fonctionnant le mieux:Comme cela fonctionne en poussant les heures de départ sur une pile, cela fonctionnera correctement pour plusieurs niveaux de
tic
s et detoc
s. Cela permet également de changer la chaîne de format de l'toc
instruction pour afficher des informations supplémentaires, ce que j'ai aimé sur laTimer
classe d'Eli .Pour une raison quelconque, je me suis préoccupé de la surcharge d'une implémentation pure Python, alors j'ai également testé un module d'extension C:
C'est pour MacOSX, et j'ai omis le code pour vérifier s'il
lvl
est hors limites par souci de concision. Bien quetictoc.res()
donne une résolution d'environ 50 nanosecondes sur mon système, j'ai trouvé que l'instabilité de la mesure de toute instruction Python se situe facilement dans la plage de la microseconde (et bien plus encore lorsqu'elle est utilisée à partir d'IPython). À ce stade, la surcharge de l'implémentation Python devient négligeable, de sorte qu'elle peut être utilisée avec la même confiance que l'implémentation C.J'ai trouvé que l'utilité de l'
tic-toc
approche -approach est pratiquement limitée aux blocs de code qui prennent plus de 10 microsecondes à exécuter. En dessous, des stratégies de calcul de la moyenne comme danstimeit
sont nécessaires pour obtenir une mesure fidèle.la source
Vous pouvez utiliser
tic
et àtoc
partir dettictoc
. Installez-le avecEt importez-les simplement dans votre script comme suit
la source
Je viens de créer un module [tictoc.py] pour réaliser des tic tocs imbriqués, ce que fait Matlab.
Et cela fonctionne de cette façon:
J'espère que cela aide.
la source
Jetez un œil au
timeit
module. Ce n'est pas vraiment équivalent mais si le code que vous voulez chronométrer est à l'intérieur d'une fonction, vous pouvez facilement l'utiliser.la source
timeit
c'est mieux pour les benchmarks. Il n'est même pas nécessaire que ce soit une fonction unique, vous pouvez passer des instructions abritement complexes.Dans le code:
Avertissement: je suis l'auteur de cette bibliothèque.
la source
Cela peut également être fait à l'aide d'un wrapper. Façon très générale de garder le temps.
L'encapsuleur de cet exemple de code encapsule n'importe quelle fonction et imprime le temps nécessaire pour exécuter la fonction:
la source
J'ai changé un peu la réponse de @Eli Bendersky pour utiliser le ctor
__init__()
et le dtor__del__()
pour faire le timing, afin qu'il puisse être utilisé plus facilement sans indenter le code d'origine:Pour l'utiliser, mettez simplement Timer ("blahblah") au début d'une portée locale. Le temps écoulé sera imprimé à la fin de la portée:
Il imprime:
la source
timer
n'est pas supprimée après le dernier appel, si un autre code suit après lafor
boucle. Pour obtenir la dernière valeur du timer, il faut supprimer ou écrasertimer
lafor
boucle après la boucle, par exemple viatimer = None
.Mise à jour de la réponse d' Eli à Python 3:
Tout comme Eli, il peut être utilisé comme gestionnaire de contexte:
Production:
Je l'ai également mis à jour pour imprimer les unités de temps rapportées (secondes) et couper le nombre de chiffres comme suggéré par Can, et avec la possibilité d'ajouter également à un fichier journal. Vous devez importer datetime pour utiliser la fonction de journalisation:
la source
En m'appuyant sur les réponses de Stefan et d'Antonimmo, j'ai fini par mettre
dans un
utils.py
module, et je l'utilise avec unPar ici
tic()
,toc()
et les imbriquer comme dans Matlabtic(1)
,toc(1)
outic('very-important-block')
,toc('very-important-block')
et minuteries avec des noms différents n'interférer(ici, toc n'imprime pas le temps écoulé, mais le renvoie.)
la source