2008-10-01 13 views
40

Ich versuche nur ein Stück Code Zeit. Der Pseudocode sieht so aus:Holen Sie sich Timer-Ticks in Python

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

Wie sieht das in Python aus?

Genauer gesagt, wie bekomme ich die Anzahl der Ticks seit Mitternacht (oder wie Python organisiert dieses Timing)?

+0

verwandt: [Zeit in Python abgelaufen?] (Http://stackoverflow.com/q/7370801/4279) – jfs

Antwort

33

Im time Modul gibt es zwei Zeitfunktionen: time und clock. time gibt Ihnen "Wand" Zeit, wenn das ist, was Sie interessieren.

Allerdings sollte der Python docs sagen, dass clock für das Benchmarking verwendet werden sollte. Beachten Sie, dass clock in getrennten Systemen unterschiedlich verhält:

  • auf MS Windows, verwendet es die Win32-Funktion Queryperformancecounter(), mit „Auflösung der Regel besser als eine Mikrosekunde“. Es hat keine besondere Bedeutung, es ist nur eine Nummer (es beginnt zu zählen, wenn Sie das erste Mal clock in Ihrem Prozess aufrufen).
 
    # ms windows 
    t0= time.clock() 
    do_something() 
    t= time.clock() - t0 # t is wall seconds elapsed (floating point) 
  • auf * nix, clock Berichte CPU-Zeit. Nun, das ist anders und höchstwahrscheinlich der Wert, den Sie wollen, da Ihr Programm kaum der einzige Prozess ist, der CPU-Zeit anfordert (selbst wenn Sie keine anderen Prozesse haben, verwendet der Kernel hin und wieder CPU-Zeit). Also, diese Zahl ist, die typischerweise smaller¹ als die Wandzeit (dh time.time() - t0), mehr sinnvoll ist, wenn der Code Benchmarking:
 
    # linux 
    t0= time.clock() 
    do_something() 
    t= time.clock() - t0 # t is CPU seconds elapsed (floating point) 

Abgesehen von all dem, das timeit Modul hat die Timer Klasse, die das Beste für das Benchmarking aus den verfügbaren Funktionen verwenden soll.

¹, es sei denn Einfädeln in die Quere kommt ...

² Python ≥3.3: Es gibt time.perf_counter() and time.process_time(). perf_counter wird vom Modul timeit verwendet.

+0

'time.clock()' kann eine schlechte Genauigkeit auf * nix haben. [Verwenden Sie 'timeeit.default_timer'] (http://stackoverflow.com/a/25823885/4279), um den besten Timer zum Messen der Zeitleistung auf verschiedenen Betriebssystemen und Python-Versionen zu erhalten. – jfs

30

Was Sie brauchen, ist time() Funktion von time Modul:

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

Sie obwohl timeit Modul für mehr Optionen verwenden können.

2
import datetime 

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

Von Mitternacht:

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

Dies berücksichtigt nicht vergangene Tage in datetime (und technisch Mikrosekunden, aber da wir nicht kümmern sich um diejenigen ...), so wird sehr ungenau sein, wenn der lange Code länger dauert als Sie denken. – leetNightshade

2

Die time module in Python gibt Ihnen Zugriff auf die Uhr() Funktion, die Zeit in Sekunden als Fließkommazurückgibt.

Verschiedene Systeme haben unterschiedliche Genauigkeit basierend auf ihrer internen Uhr Setup (Ticks pro Sekunde), aber es ist in der Regel mindestens 20 Millisekunden, und in einigen Fällen besser als ein paar Mikrosekunden.

-Adam

4

Hier ist eine Lösung, die ich vor kurzem mit gestartet:

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

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

Sie verwenden es wie folgt aus (Sie müssen mindestens Python 2.5):

with Timer(): 
    do_long_code() 

Wenn Ihr Code abgeschlossen ist, automatisch Timer ausdruckt die Laufzeit. Süss! Wenn ich versuche, im Python-Interpreter schnell etwas einzubauen, ist dies der einfachste Weg.

Und hier ist eine Beispielimplementierung von 'now' und 'format_delta', aber zögern Sie nicht, Ihre bevorzugte Timing- und Formatierungsmethode zu verwenden.

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 

Bitte lassen Sie mich wissen, wenn Sie eine bevorzugte Formatierungsmethode haben, oder wenn es ein einfacherer Weg, um all dies zu tun!

0

Wenn Sie viele Aussagen haben Sie Zeit möchten, können Sie so etwas wie folgt verwenden:

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

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

Dann könnte Ihr Code wie folgt aussehen:

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()) 

Auf diese Weise brauchen Sie nicht zu Geben Sie t = time() vor jedem Block und 1000 * (time() - t) danach ein, während Sie immer noch die Kontrolle über die Formatierung behalten (obwohl Sie das auch problemlos in Ticket setzen könnten).

Es ist ein minimaler Gewinn, aber ich denke, es ist irgendwie bequem.

Verwandte Themen