web-dev-qa-db-fra.com

Obtenir des ticks de minuterie en Python

J'essaie juste de chronométrer un morceau de code. Le pseudocode ressemble à:

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 quand Python organise ce timing)?

40
andrewrk

Dans le module time, il existe deux fonctions de minutage: time et clock. time vous donne le temps de "mur", si c'est ce qui compte pour vous.

Cependant, les python docs disent que clock devrait être utilisé pour l’analyse comparative. Notez que clock se comporte différemment dans des systèmes distincts:

  • sur MS Windows, il utilise la fonction Win32 QueryPerformanceCounter (), avec "résolution généralement meilleure qu'une microseconde". Cela n'a pas de signification particulière, c'est juste un nombre (il commence à compter dès le premier appel de clock dans votre processus).
 # ms windows 
 t0 = time.clock () 
 faire quelque chose()
 t = time.clock () - t0 # t est le temps écoulé depuis la mur (virgule flottante) 
  • sur * nix, clock indique le temps processeur. Maintenant, c'est différent, et probablement la valeur que vous voulez, puisque votre programme est rarement le seul processus demandant du temps CPU (même si vous n'avez pas d'autres processus, le noyau utilise le temps CPU de temps en temps). Ainsi, ce nombre, qui est généralement inférieur¹ au temps sur le mur (c'est-à-dire time.time () - t0), est plus significatif lorsque l'on compare le code:
 # linux 
 t0 = time.clock () 
 faire quelque chose()
 t = time.clock () - t0 # t est le nombre de secondes UC écoulées (virgule flottante) 

En dehors de tout cela, le module timeit a la classe Timer qui est supposée utiliser ce qui est le mieux pour comparer les fonctionnalités disponibles.

¹ à moins que le filetage ne gêne…

² Python ≥3.3: il existe time.perf_counter() ET time.process_time() . perf_counter est utilisé par le module timeit.

33
tzot

Ce dont vous avez besoin est la fonction time() du module time:

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

Vous pouvez utiliser timeit module pour plus d'options.

30
blackwing

Voici une solution que j'ai 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 l'utilisez comme ceci (vous avez besoin d'au moins Python 2.5):

with Timer():
    do_long_code()

Lorsque votre code est terminé, Timer affiche automatiquement le temps d'exécution. Sucré! Si j'essaie de mettre rapidement quelque chose dans l'interpréteur Python, c'est le moyen le plus simple. 

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

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 formatage préférée, ou s'il existe un moyen plus facile de faire tout cela!

4
leetNightshade
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
2
Harley Holcombe

Le module time en python vous donne accès à la fonction clock (), qui renvoie le temps en secondes sous forme de virgule flottante.

Différents systèmes auront une précision différente en fonction de la configuration de leur horloge interne (ticks par seconde), mais elle est généralement inférieure à 20 millisecondes et parfois supérieure à quelques microsecondes.

-Adam

2
Adam Davis

Si vous voulez chronométrer plusieurs déclarations, 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 de taper t = time() avant chaque bloc et 1000 * (time() - t) après, tout en gardant le contrôle du formatage (bien que vous puissiez facilement le mettre dans Ticket également).

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

0
Mark