it-swarm.com.de

In Python abgelaufene Zeit messen?

Was ich möchte, ist, die Zeit irgendwo in meinem Code zu zählen und dann die abgelaufene Zeit zu erhalten, um die Zeit zu messen, die für die Ausführung weniger Funktionen benötigt wurde. Ich denke, ich verwende das Zeitmodul falsch, aber die Dokumente sind für mich verwirrend.

import timeit

start = timeit.timeit()
print "hello"
end = timeit.timeit()
print end - start
783
gilbert8

Wenn Sie nur die abgelaufene Zeit der Wanduhr zwischen zwei Punkten messen möchten, können Sie time.time() verwenden:

import time

start = time.time()
print("hello")
end = time.time()
print(end - start)

Dies gibt die Ausführungszeit in Sekunden an.

Eine andere Option seit 3.3 ist die Verwendung von perf_counter oder process_time , abhängig von Ihren Anforderungen. Vor 3.3 wurde empfohlen, time.clock (Danke Amber ) zu verwenden. Es ist jedoch derzeit veraltet:

Geben Sie unter Unix die aktuelle Prozessorzeit als Gleitkommazahl zurück in Sekunden ausgedrückt. Die Präzision und in der Tat die Definition von der Bedeutung von "Prozessorzeit" hängt von der C-Funktion ab mit dem gleichen Namen.

Unter Windows gibt diese Funktion die seit der .__ verstrichenen Sekunden der Wanduhr zurück. erster Aufruf dieser Funktion als Fließkommazahl basierend auf der Win32-Funktion QueryPerformanceCounter(). Die Auflösung ist normalerweise besser als eine Mikrosekunde.

Veraltet seit Version 3.3: Das Verhalten dieser Funktion hängt von .__ ab. auf der Plattform: Verwenden Sie perf_counter() oder process_time() statt, abhängig von Ihren Anforderungen, um ein genau definiertes Verhalten zu haben.

1012
NPE

Verwenden Sie timeit.default_timer anstelle von timeit.timeit. Ersteres stellt automatisch die beste auf Ihrer Plattform und Python-Version verfügbare Uhr bereit:

from timeit import default_timer as timer

start = timer()
# ...
end = timer()
print(end - start) # Time in seconds, e.g. 5.38091952400282

timeit.default_timer wird je nach Betriebssystem time.time () oder time.clock () zugewiesen. Auf Python 3.3+ ist default_timer auf allen Plattformen time.perf_counter () . Siehe Python - time.clock () vs. time.time () - Genauigkeit?

Siehe auch:

420
jfs

Nur Python 3:

Da time.clock () seit Python 3.3 veraltet ist, sollten Sie time.perf_counter() für systemweites Timing oder time.process_time() für prozessweites Timing verwenden, genau wie Sie es verwendet haben time.clock() verwenden:

import time

t = time.process_time()
#do some stuff
elapsed_time = time.process_time() - t

Die neue Funktion process_time enthält keine Zeit, die während des Schlafens verstrichen ist.

99
Pierre Prinetti

Bei einer bestimmten Funktion möchten Sie

test.py:

def foo(): 
    # print "hello"   
    return "hello"

die einfachste Möglichkeit, timeit zu verwenden, besteht darin, sie von der Befehlszeile aus aufzurufen:

% python -mtimeit -s'import test' 'test.foo()'
1000000 loops, best of 3: 0.254 usec per loop

Versuchen Sie nicht, time.time oder time.clock (naiv) zu verwenden, um die Geschwindigkeit von Funktionen zu vergleichen. Sie können irreführende Ergebnisse liefern .

PS. Setzen Sie keine Druckanweisungen in eine Funktion, die Sie zeitlich festlegen möchten. Andernfalls hängt die gemessene Zeit von der Geschwindigkeit des Terminals ab.

73
unutbu

Ich bevorzuge das. timeit doc ist viel zu verwirrend. 

from datetime import datetime 

start_time = datetime.now() 

# INSERT YOUR CODE 

time_elapsed = datetime.now() - start_time 

print('Time elapsed (hh:mm:ss.ms) {}'.format(time_elapsed))

Beachten Sie, dass hier keine Formatierung stattfindet. Ich habe gerade hh:mm:ss in den Ausdruck geschrieben, damit man time_elapsed interpretieren kann.

45
user1761806

Es macht Spaß, dies mit einem Kontext-Manager zu tun, der die Startzeit beim Eintritt in einen with-Block automatisch speichert und dann beim Beenden des Blocks die Endzeit einfriert. Mit ein bisschen Trick, können Sie sogar eine laufende Ablaufsammlung innerhalb des Blocks von derselben Kontext-Manager-Funktion abrufen. 

Die Kernbibliothek hat dies nicht (sollte aber wahrscheinlich). Einmal an Ort und Stelle können Sie Folgendes tun:

with elapsed_timer() as elapsed:
    # some lengthy code
    print( "midpoint at %.2f seconds" % elapsed() )  # time so far
    # other lengthy code

print( "all done at %.2f seconds" % elapsed() )

Hier ist contextmanager code ausreichend, um den Trick auszuführen:

from contextlib import contextmanager
from timeit import default_timer

@contextmanager
def elapsed_timer():
    start = default_timer()
    elapser = lambda: default_timer() - start
    yield lambda: elapser()
    end = default_timer()
    elapser = lambda: end-start

Und ein lauffähiger Demo-Code:

import time

with elapsed_timer() as elapsed:
    time.sleep(1)
    print(elapsed())
    time.sleep(2)
    print(elapsed())
    time.sleep(3)

Beachten Sie, dass bei dieser Funktion der Rückgabewert von elapsed() beim Beenden des Blocks eingefroren wird und weitere Aufrufe dieselbe Dauer (von etwa 6 Sekunden in diesem Spielzeugbeispiel) zurückgeben. 

43
gojomo

Wenn Sie time.time zum Messen der Ausführung verwenden, erhalten Sie die Gesamtausführungszeit Ihrer Befehle, einschließlich der Laufzeit, die andere Prozesse auf Ihrem Computer verbringen. Dies ist die Zeit, die der Benutzer bemerkt, ist aber nicht gut, wenn Sie verschiedene Codeausschnitte/Algorithmen/Funktionen/vergleichen möchten.

Weitere Informationen zu timeit:

Wenn Sie einen tieferen Einblick in die Profilerstellung erhalten möchten:

Update: Ich habe im letzten Jahr sehr oft http://pythonhosted.org/line_profiler/ verwendet und finde es sehr hilfreich und empfehle, es anstelle des Pythons-Profilmoduls zu verwenden.

24
rocksportrocker

Hier ist eine kleine Timer-Klasse, die den String "hh: mm: ss" zurückgibt: 

class Timer:
  def __init__(self):
    self.start = time.time()

  def restart(self):
    self.start = time.time()

  def get_time_hhmmss(self):
    end = time.time()
    m, s = divmod(end - self.start, 60)
    h, m = divmod(m, 60)
    time_str = "%02d:%02d:%02d" % (h, m, s)
    return time_str

Verwendungszweck: 

# Start timer
my_timer = Timer()

# ... do something

# Get time string:
time_hhmmss = my_timer.get_time_hhmmss()
print("Time elapsed: %s" % time_hhmmss )

# ... use the timer again
my_timer.restart()

# ... do something

# Get time:
time_hhmmss = my_timer.get_time_hhmmss()

# ... etc
18
Danijel

Die Module pPrython cProfile und pstats bieten eine großartige Unterstützung für die Messung der in bestimmten Funktionen abgelaufenen Zeit, ohne dass Code um die vorhandenen Funktionen hinzugefügt werden muss.

Zum Beispiel, wenn Sie ein Python-Skript timeFunctions.py haben:

import time

def hello():
    print "Hello :)"
    time.sleep(0.1)

def thankyou():
    print "Thank you!"
    time.sleep(0.05)

for idx in range(10):
    hello()

for idx in range(100):
    thankyou()

Um den Profiler auszuführen und Statistiken für die Datei zu generieren, können Sie einfach Folgendes ausführen:

python -m cProfile -o timeStats.profile timeFunctions.py

Dazu verwenden Sie das Modul cProfile, um alle Funktionen in timeFunctions.py zu profilieren und die Statistiken in der Datei timeStats.profile zu erfassen. Beachten Sie, dass wir dem vorhandenen Modul (timeFunctions.py) keinen Code hinzufügen mussten. Dies kann mit jedem Modul erfolgen.

Sobald Sie die Statistikdatei haben, können Sie das pstats-Modul wie folgt ausführen:

python -m pstats timeStats.profile

Dadurch wird der interaktive Statistikbrowser ausgeführt, der Ihnen eine Menge Funktionen von Nice bietet. Für Ihren speziellen Anwendungsfall können Sie einfach die Statistiken für Ihre Funktion überprüfen. In unserem Beispiel zeigt das Überprüfen der Statistiken für beide Funktionen Folgendes:

Welcome to the profile statistics browser.
timeStats.profile% stats hello
<timestamp>    timeStats.profile

         224 function calls in 6.014 seconds

   Random listing order was used
   List reduced from 6 to 1 due to restriction <'hello'>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       10    0.000    0.000    1.001    0.100 timeFunctions.py:3(hello)

timeStats.profile% stats thankyou
<timestamp>    timeStats.profile

         224 function calls in 6.014 seconds

   Random listing order was used
   List reduced from 6 to 1 due to restriction <'thankyou'>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      100    0.002    0.000    5.012    0.050 timeFunctions.py:7(thankyou)

Das Dummy-Beispiel macht nicht viel, gibt aber eine Vorstellung davon, was getan werden kann. Das Beste an diesem Ansatz ist, dass ich keinen der vorhandenen Codes bearbeiten muss, um diese Nummern zu erhalten und natürlich bei der Profilerstellung zu helfen.

16
sanchitarora

Hier ist ein weiterer Kontextmanager für Timing-Code -

Verwendungszweck: 

from benchmark import benchmark

with benchmark("Test 1+1"):
    1+1
=>
Test 1+1 : 1.41e-06 seconds

oder wenn Sie den Zeitwert benötigen

with benchmark("Test 1+1") as b:
    1+1
print(b.time)
=>
Test 1+1 : 7.05e-07 seconds
7.05233786763e-07

benchmark.py:

from timeit import default_timer as timer

class benchmark(object):

    def __init__(self, msg, fmt="%0.3g"):
        self.msg = msg
        self.fmt = fmt

    def __enter__(self):
        self.start = timer()
        return self

    def __exit__(self, *args):
        t = timer() - self.start
        print(("%s : " + self.fmt + " seconds") % (self.msg, t))
        self.time = t

Adaptiert von http://dabeaz.blogspot.fr/2010/02/context-manager-for-timing-benchmarks.html

16
Brian Burns

Verwenden Sie das Profiler-Modul. Es gibt ein sehr detailliertes Profil.

import profile
profile.run('main()')

es gibt etwas aus wie:

          5 function calls in 0.047 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.000    0.000 :0(exec)
        1    0.047    0.047    0.047    0.047 :0(setprofile)
        1    0.000    0.000    0.000    0.000 <string>:1(<module>)
        0    0.000             0.000          profile:0(profiler)
        1    0.000    0.000    0.047    0.047 profile:0(main())
        1    0.000    0.000    0.000    0.000 two_sum.py:2(twoSum)

Ich fand es sehr informativ.

14
Leonid Ganeline

(Nur bei Ipython) können Sie % timeit verwenden, um die durchschnittliche Verarbeitungszeit zu messen:

def foo():
    print "hello"

und dann: 

%timeit foo()

das Ergebnis ist so etwas wie:

10000 loops, best of 3: 27 µs per loop
12
Eyal Ch

Es ist jetzt 2019. Lass es uns mit einer präziseren Methode machen:

from ttictoc import TicToc
t = TicToc() ## TicToc("name")
t.tic();
# your code ...
t.toc();
print(t.elapsed)

Vorteile dieses Ansatzes gegenüber anderen:

  1. Kurz und unkompliziert. Es ist nicht erforderlich, dass der Programmierer zusätzliche Variablen schreibt wie:
    t1 = time ()
    t2 = time ()
    verstrichen = t2 - t1
  2. Mit dem Verschachteln
t = TicToc(nested=True)
t.tic()
some code1...
t.tic()
some code2...
t.tic()
some code3...
print(t.toc()) # Prints time for code 3 
print(t.toc()) # Prints time for code 2 with code 3
print(t.toc()) # Prints time for code 1 with code 2 and 3
  1. Bewahren Sie die Namen Ihres Tictocs auf.
t = TicToc("save user")
print(t.name)

Bitte beziehen Sie sich auf diese Link für detailliertere Anweisungen.

9
mervyn

auf Python3:

from time import sleep, perf_counter as pc
t0 = pc()
sleep(1)
print(pc()-t0)

elegant und kurz.

9
DmitrySemenov

Eine super Antwort später, aber vielleicht dient sie jemandem. Dies ist ein Weg, der meiner Meinung nach super sauber ist.

import time

def timed(fun, *args):
    s = time.time()
    r = fun(*args)
    print('{} execution took {} seconds.'.format(fun.__name__, time.time()-s))
    return(r)

timed(print, "Hello")

Beachten Sie, dass "print" eine Funktion in Python 3 und nicht in Python 2.7 ist. Es funktioniert jedoch mit jeder anderen Funktion. Prost!

9
Andreas Herman

Ich mag es einfach (Python 3):

from timeit import timeit

timeit(lambda: print("hello"))

Die Ausgabe beträgt Mikrosekunden für eine einzelne Ausführung:

2.430883963010274

Erklärung: timeit führt die anonyme Funktion aus 1 Million Mal standardmäßig und das Ergebnis wird in Sekunden angegeben . Daher ist das Ergebnis für 1 einzelne Ausführung gleich groß, jedoch in Mikrosekunden im Durchschnitt.


Fügen Sie für langsame Operationen eine niedrigere Anzahl von Iterationen hinzu, oder Sie könnten ewig warten:

import time

timeit(lambda: time.sleep(1.5), number=1)

Die Ausgabe erfolgt immer in Sekunden für die Gesamtzahl der Iterationen :

1.5015795179999714
7
David

Wir können auch Zeit in vom Menschen lesbare Zeit umrechnen.

import time, datetime

start = time.clock()

def num_multi1(max):
    result = 0
    for num in range(0, 1000):
        if (num % 3 == 0 or num % 5 == 0):
            result += num

    print "Sum is %d " % result

num_multi1(1000)

end = time.clock()
value = end - start
timestamp = datetime.datetime.fromtimestamp(value)
print timestamp.strftime('%Y-%m-%d %H:%M:%S')
6
Kamlesh Verma

Hier sind meine Ergebnisse, nachdem ich hier viele gute Antworten sowie einige andere Artikel durchgelesen habe.

Erstens möchten Sie immer timeit und nicht time.time (und in vielen Fällen Perf Counter-APIs) verwenden, weil 

  1. timeit wählt den besten für Ihr Betriebssystem und Ihre Python-Version verfügbaren Zeitgeber aus. 
  2. timeit deaktiviert die Garbage Collection. Dies ist jedoch nichts, was Sie vielleicht nicht wollen oder nicht.

Das Problem ist nun, dass Timeit nicht so einfach zu bedienen ist, weil es ein Setup erfordert und die Dinge hässlich werden, wenn Sie eine Menge Importe haben. Idealerweise möchten Sie einfach nur einen Dekorateur oder with Block verwenden und die Zeit messen. Leider ist dafür nichts eingebaut, daher habe ich ein kleines Hilfsprogramm erstellt.

Timing-Dienstmodul

# utils.py
from functools import wraps
import gc
import timeit

def MeasureTime(f):
    @wraps(f)
    def _wrapper(*args, **kwargs):
        gcold = gc.isenabled()
        gc.disable()
        start_time = timeit.default_timer()
        try:
            result = f(*args, **kwargs)
        finally:
            elapsed = timeit.default_timer() - start_time
            if gcold:
                gc.enable()
            print('Function "{}": {}s'.format(f.__name__, elapsed))
        return result
    return _wrapper

class MeasureBlockTime:
    def __init__(self,name="(block)", no_print = False, disable_gc = True):
        self.name = name
        self.no_print = no_print
        self.disable_gc = disable_gc
    def __enter__(self):
        if self.disable_gc:
            self.gcold = gc.isenabled()
            gc.disable()
        self.start_time = timeit.default_timer()
    def __exit__(self,ty,val,tb):
        self.elapsed = timeit.default_timer() - self.start_time
        if self.disable_gc and self.gcold:
            gc.enable()
        if not self.no_print:
            print('Function "{}": {}s'.format(self.name, self.elapsed))
        return False #re-raise any exceptions

So stellen Sie Funktionen fest

Jetzt können Sie jede Funktion zeitlich festlegen, indem Sie einen Dekorateur davor stellen:

import utils

@utils.MeasureTime
def MyBigFunc():
    #do something time consuming
    for i in range(10000):
        print(i)

Wie Zeitcodeblöcke setzen

Wenn Sie einen Teil des Codes zeitlich festlegen möchten, fügen Sie ihn einfach in den with-Block ein:

import utils

#somewhere in my code

with utils.MeasureBlockTime("MyBlock"):
    #do something time consuming
    for i in range(10000):
        print(i)

# rest of my code

Vorteile

Es gibt mehrere halb hinterlegte Versionen, daher möchte ich einige Highlights hervorheben:

  1. Verwenden Sie aus den oben beschriebenen Gründen einen Timer aus Zeit statt Zeit.
  2. GC während des Timings deaktivieren.
  3. Decorator akzeptiert Funktionen mit benannten oder unbenannten Parametern.
  4. Möglichkeit, das Drucken im Block-Timing zu deaktivieren (verwenden Sie with utils.MeasureBlockTime() as t und dann t.elapsed).
  5. Fähigkeit, gc für Block-Timing aktiviert zu lassen.
6
Shital Shah

Eine weitere Möglichkeit zur Verwendung von timeit :

from timeit import timeit

def func():
    return 1 + 1

time = timeit(func, number=1)
print(time)
6
raacer

Ich habe dafür eine Bibliothek erstellt. Wenn Sie eine Funktion messen möchten, können Sie dies einfach so tun 


from pythonbenchmark import compare, measure
import time

a,b,c,d,e = 10,10,10,10,10
something = [a,b,c,d,e]

@measure
def myFunction(something):
    time.sleep(0.4)

@measure
def myOptimizedFunction(something):
    time.sleep(0.2)

myFunction(input)
myOptimizedFunction(input)

https://github.com/Karlheinzniebuhr/pythonbenchmark

5
karlpy

Gehen Sie wie folgt vor, um einen Einblick in alle Funktionsaufrufe zu erhalten:

%load_ext snakeviz
%%snakeviz

Es werden nur die 2 Codezeilen in einem Jupyter-Notizbuch und benötigt Es wird ein schönes interaktives Diagramm erstellt. Zum Beispiel:

enter image description here

Hier ist der Code. Auch hier sind die 2 Zeilen, die mit % beginnen, die einzigen zusätzlichen Codezeilen, die zur Verwendung von snakeviz erforderlich sind:

# !pip install snakeviz
%load_ext snakeviz
import glob
import hashlib

%%snakeviz

files = glob.glob('*.txt')
def print_files_hashed(files):
    for file in files:
        with open(file) as f:
            print(hashlib.md5(f.read().encode('utf-8')).hexdigest())
print_files_hashed(files)

Es scheint auch möglich zu sein, snakeviz außerhalb von Notebooks auszuführen. Mehr Infos auf der snakeviz website .

5

Sie können die Zeit verwenden.

Hier ein Beispiel zum Testen von naive_func, das Parameter mit Python REPL verwendet:

>>> import timeit                                                                                         

>>> def naive_func(x):                                                                                    
...     a = 0                                                                                             
...     for i in range(a):                                                                                
...         a += i                                                                                        
...     return a                                                                                          

>>> def wrapper(func, *args, **kwargs):                                                                   
...     def wrapper():                                                                                    
...         return func(*args, **kwargs)                                                                  
...     return wrapper                                                                                    

>>> wrapped = wrapper(naive_func, 1_000)                                                                  

>>> timeit.timeit(wrapped, number=1_000_000)                                                              
0.4458435332577161  

Sie benötigen keine Wrapper-Funktion, wenn die Funktion keine Parameter enthält. 

4
Vlad Bezden

Messzeit in Sekunden:

from timeit import default_timer as timer
from datetime import timedelta

start = timer()
end = timer()
print(timedelta(seconds=end-start))
1
Gal Bracha

Die einzige Möglichkeit, die mir einfällt, ist time.time().

import time
start = time.time()
sleep(5) #just to give it some delay to show it working
finish = time.time()
elapsed = finish - start
print(elapsed)

Hoffe das wird helfen.

0
Trooper Z