Question

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."

En quoi cela ressemble-t-il en Python?

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

Était-ce utile?

La solution

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

Cependant, les docs du python indiquent que horloge 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 une "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 votre horloge dans votre processus).
    # ms windows
    t0= time.clock()
    do_something()
    t= time.clock() - t0 # t is wall seconds elapsed (floating point)
  • sur * nix, clock rapporte 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'autre 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.-à-d. Time.time () - t0), a plus de sens lorsque le code de comparaison:
    # linux
    t0= time.clock()
    do_something()
    t= time.clock() - t0 # t is CPU seconds elapsed (floating point)

En dehors de tout cela, le module timeit dispose du minuteur . classe censée utiliser ce qui est le mieux pour effectuer des analyses comparatives à partir des fonctionnalités disponibles.

¹ à moins que les fils ne vous gênent…

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

Autres conseils

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

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.

Voici une solution que j'ai récemment utilisée:

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 biffer 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

Faites-moi savoir si vous avez une méthode de formatage préférée ou s'il existe un moyen plus simple de faire tout cela!

Le module de temps en python vous donne accès à l'horloge () fonction, 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, dans certains cas, meilleure que quelques microsecondes.

-Adam

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

Si vous souhaitez 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

Votre code pourrait alors 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 saisir t = time () avant chaque bloc et 1000 * (time () - t) après, tout en conservant contrôle sur le 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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top