2008-10-01 9 views
40

J'essaie juste de chronométrer un morceau de code. Le pseudo-code ressemble à:Obtenir des ticks de minuterie en Python

start = get_ticks() 
do_long_code() 
print "It took " + (get_ticks() - start) + " seconds." 

Comment cela ressemble-t-il en Python?

Plus précisément, comment puis-je obtenir le nombre de ticks depuis minuit (ou bien Python organise ce timing)?

+0

related: [Mesurer le temps écoulé en Python?] (Http://stackoverflow.com/q/7370801/4279) – jfs

Répondre

33

Dans le module time, il y a deux fonctions de synchronisation: time et clock. time vous donne le temps "mur", si c'est ce qui vous intéresse.

Cependant, le python docs dit que clock devrait être utilisé pour l'analyse comparative. Notez que clock se comporte différents dans des systèmes séparés:

  • sur MS Windows, il utilise la fonction Win32 QueryPerformanceCounter(), avec « la résolution généralement mieux qu'une microseconde ». Il n'a pas de signification particulière, c'est juste un nombre (il commence à compter la première fois que vous appelez clock dans votre processus).
 
    # ms windows 
    t0= time.clock() 
    do_something() 
    t= time.clock() - t0 # t is wall seconds elapsed (floating point) 
  • sur * nix, clock rapports de temps CPU. Maintenant, c'est différent, et très probablement la valeur que vous voulez, puisque votre programme est rarement le seul processus demandant le temps CPU (même si vous n'avez pas d'autres processus, le noyau utilise le temps CPU de temps en temps). Donc, ce chiffre, qui est généralement smaller¹ que le temps de la paroi (c.-à-time.time() - t0), est plus significatif lorsque le code d'analyse comparative:
 
    # linux 
    t0= time.clock() 
    do_something() 
    t= time.clock() - t0 # t is CPU seconds elapsed (floating point) 

En dehors de tout cela, le module a timeitTimer classe qui est censé utiliser ce qu'il y a de mieux pour l'analyse comparative des fonctionnalités disponibles.

¹ à moins de filetage est dans la manière ...

² Python ≥3.3: il y a time.perf_counter() and time.process_time(). perf_counter est utilisé par le module timeit.

+0

'time.clock()' peut avoir une mauvaise précision sur * nix. [Utilisez 'timeit.default_timer'] (http://stackoverflow.com/a/25823885/4279), pour obtenir le meilleur timer pour mesurer les performances temporelles sur différents OS et versions Python. – jfs

30

Qu'est-ce que vous avez besoin est fonction de time()time Module:

import time 
start = time.time() 
do_long_code() 
print "it took", time.time() - start, "seconds." 

Vous pouvez utiliser le module timeit pour plus d'options bien.

2
import datetime 

start = datetime.datetime.now() 
do_long_code() 
finish = datetime.datetime.now() 
delta = finish - start 
print delta.seconds 

à partir de minuit:

import datetime 

midnight = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) 
now = datetime.datetime.now() 
delta = now - midnight 
print delta.seconds 
+0

Cela ne tient pas compte des jours passés dans datetime (et techniquement microsecondes, mais puisque nous ne le faisons pas attention à ceux ...), sera donc très inexact si le code long prend plus de temps que vous ne le pensez. – leetNightshade

2

Le time module en python vous donne accès à la fonction horloge(), qui retourne le temps en secondes comme point flottant.

Différents systèmes auront une précision différente en fonction de leur configuration d'horloge interne (ticks par seconde), mais il est généralement inférieur à 20 millisecondes et, dans certains cas, supérieur à quelques microsecondes.

-Adam

4

est ici une solution que je commencé à utiliser récemment:

class Timer: 
    def __enter__(self): 
     self.begin = now() 

    def __exit__(self, type, value, traceback): 
     print(format_delta(self.begin, now())) 

Vous pouvez l'utiliser comme ceci (vous devez au moins Python 2.5):

with Timer(): 
    do_long_code() 

Lorsque votre code se termine, la minuterie imprime automatiquement le temps d'exécution. Doux! Si j'essaye de mettre rapidement quelque chose au point dans l'interpréteur Python, c'est la façon la plus simple d'y aller.

Et voici un exemple d'implémentation de 'now' et 'format_delta', mais n'hésitez pas à utiliser votre timing et votre méthode de formatage préférés.

import datetime 

def now(): 
    return datetime.datetime.now() 

# Prints one of the following formats*: 
# 1.58 days 
# 2.98 hours 
# 9.28 minutes # Not actually added yet, oops. 
# 5.60 seconds 
# 790 milliseconds 
# *Except I prefer abbreviated formats, so I print d,h,m,s, or ms. 
def format_delta(start,end): 

    # Time in microseconds 
    one_day = 86400000000 
    one_hour = 3600000000 
    one_second = 1000000 
    one_millisecond = 1000 

    delta = end - start 

    build_time_us = delta.microseconds + delta.seconds * one_second + delta.days * one_day 

    days = 0 
    while build_time_us > one_day: 
     build_time_us -= one_day 
     days += 1 

    if days > 0: 
     time_str = "%.2fd" % (days + build_time_us/float(one_day)) 
    else: 
     hours = 0 
     while build_time_us > one_hour: 
      build_time_us -= one_hour 
      hours += 1 
     if hours > 0: 
      time_str = "%.2fh" % (hours + build_time_us/float(one_hour)) 
     else: 
      seconds = 0 
      while build_time_us > one_second: 
       build_time_us -= one_second 
       seconds += 1 
      if seconds > 0: 
       time_str = "%.2fs" % (seconds + build_time_us/float(one_second)) 
      else: 
       ms = 0 
       while build_time_us > one_millisecond: 
        build_time_us -= one_millisecond 
        ms += 1 
       time_str = "%.2fms" % (ms + build_time_us/float(one_millisecond)) 
    return time_str 

S'il vous plaît laissez-moi savoir si vous avez une méthode de mise en forme préférée, ou s'il y a un moyen plus facile de faire tout cela!

0

Si vous avez beaucoup de déclarations que vous voulez temps, vous pouvez utiliser quelque chose comme ceci:

class Ticker: 
    def __init__(self): 
     self.t = clock() 

    def __call__(self): 
     dt = clock() - self.t 
     self.t = clock() 
     return 1000 * dt 

Ensuite, votre code pourrait ressembler à:

tick = Ticker() 
# first command 
print('first took {}ms'.format(tick()) 
# second group of commands 
print('second took {}ms'.format(tick()) 
# third group of commands 
print('third took {}ms'.format(tick()) 

De cette façon, vous n'avez pas besoin tapez t = time() avant chaque bloc et 1000 * (time() - t) après, tout en gardant le contrôle sur le formatage (même si vous pouvez facilement mettre cela en Ticket aussi).

C'est un gain minimal, mais je pense que c'est plutôt pratique.

Questions connexes