Jak mierzyć czas między wierszami kodu w Pythonie?


101

Więc w Javie możemy zrobić Jak mierzyć czas potrzebny do wykonania funkcji

Ale jak to się robi w Pythonie? Aby zmierzyć czas rozpoczęcia i zakończenia między wierszami kodów? Coś, co to robi:

import some_time_library

starttime = some_time_library.some_module()
code_tobe_measured() 
endtime = some_time_library.some_module()

time_taken = endtime - starttime

Odpowiedzi:


159

Jeśli chcesz zmierzyć czas procesora, możesz użyć time.process_time()dla Python 3.3 i nowszych:

import time
start = time.process_time()
# your code here    
print(time.process_time() - start)

Pierwsze połączenie włącza stoper, a drugie połączenie informuje, ile sekund upłynęło.

Istnieje również funkcja time.clock(), ale jest przestarzała od Pythona 3.3 i zostanie usunięta w Pythonie 3.8.

Istnieją lepsze narzędzia do profilowania, takie jak timeiti profilejednak time.process_time () mierzy czas procesora i właśnie o to pytasz.

Jeśli zamiast tego chcesz mierzyć zegar ścienny, użyj time.time().


53
To nie jest sposób, w jaki używasz time.clock()i time.clock()mierzy czas procesora w systemie Unix, ale czas ściany w systemie Windows. Lepiej jest używać, gdy time.time()zachowanie nie różni się w zależności od systemu operacyjnego. stackoverflow.com/questions/85451/…
Tim

4
Dobra obserwacja, @Tim. Jednak inny post na to samo pytanie cytuje dokument pythona o time.clock (), że „jest to funkcja używana do testowania porównawczego Pythona lub algorytmów czasowych”. Myślę, że chodzi o to, co tak naprawdę chcesz zmierzyć.
Yevgen Yampolskiy

1
Bardzo złą rzeczą w przypadku time.time () jest to, że ma na niego wpływ synchronizacja czasu ntpdate itp. Powiedziałbym, że time.clock () byłby jedyną niezawodną alternatywą z tego powodu
www.jensolsson.se

4
DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead
ismailarilik

2
Hmmm ... nie jestem pewien, co robię źle. Wymieniłem # your code herez time.sleep(10)i dostał 0,0 sekundy. Dodanie for i in range(10000):/passdało te same wyniki. W każdych okolicznościach, które próbowałem, time.process_time()zawsze zwraca tę samą liczbę. Otrzymałem oczekiwane rezultaty, używając time.perf_counter()jednak
biscuit314

58

Możesz także skorzystać z timebiblioteki:

import time

start = time.time()

# your code

# end

print(f'Time: {time.time() - start}')

1
@Hayat - ta metoda zwraca czas jako liczbę zmiennoprzecinkową wyrażoną w sekundach od epoki, w UTC. [ docs.python.org/3/library/time.html]
Anumoy Sutradhar

@AnumoySutradhar niezupełnie, ponieważ odejmuje epokę od epoki, dostajesz różnicę czasu między tymi dwoma czasami.
Nasta

28

Za pomocą małej klasy wygody możesz zmierzyć czas spędzony w wierszach z wcięciem w następujący sposób:

with CodeTimer():
   line_to_measure()
   another_line()
   # etc...

Który pokaże co następuje po zakończeniu wykonywania wciętej linii (wierszy):

Code block took: x.xxx ms

AKTUALIZACJA: Możesz teraz uzyskać zajęcia za pomocą, pip install linetimera następnie from linetimer import CodeTimer. Zobacz ten projekt GitHub .

Kod dla powyższej klasy:

import timeit

class CodeTimer:
    def __init__(self, name=None):
        self.name = " '"  + name + "'" if name else ''

    def __enter__(self):
        self.start = timeit.default_timer()

    def __exit__(self, exc_type, exc_value, traceback):
        self.took = (timeit.default_timer() - self.start) * 1000.0
        print('Code block' + self.name + ' took: ' + str(self.took) + ' ms')

Następnie możesz nazwać bloki kodu, które chcesz zmierzyć:

with CodeTimer('loop 1'):
   for i in range(100000):
      pass

with CodeTimer('loop 2'):
   for i in range(100000):
      pass

Code block 'loop 1' took: 4.991 ms
Code block 'loop 2' took: 3.666 ms

I zagnieździć je:

with CodeTimer('Outer'):
   for i in range(100000):
      pass

   with CodeTimer('Inner'):
      for i in range(100000):
         pass

   for i in range(100000):
      pass

Code block 'Inner' took: 2.382 ms
Code block 'Outer' took: 10.466 ms

Odnośnie timeit.default_timer(), używa najlepszego timera opartego na wersji systemu operacyjnego i Pythona, zobacz tę odpowiedź .


11

Zawsze wolę sprawdzać czas w godzinach, minutach i sekundach (% H:% M:% S):

from datetime import datetime
start = datetime.now()
# your code
end = datetime.now()
time_taken = end - start
print('Time: ',time_taken) 

wynik:

Time:  0:00:00.000019

3

Szukałem sposobu, jak wyprowadzić sformatowany czas przy użyciu minimalnego kodu, więc oto moje rozwiązanie. Wiele osób i tak korzysta z Pand, więc w niektórych przypadkach może to zaoszczędzić na dodatkowych importach bibliotek.

import pandas as pd
start = pd.Timestamp.now()
# code
print(pd.Timestamp.now()-start)

Wynik:

0 days 00:05:32.541600

Poleciłbym użyć tego, jeśli precyzja czasu nie jest najważniejsza, w przeciwnym razie użyj timebiblioteki:

%timeit pd.Timestamp.now() wyjścia 3,29 µs ± 214 ns na pętlę

%timeit time.time() wyjścia 154 ns ± 13,3 ns na pętlę


3

Umieszczenie kodu w funkcji, a następnie użycie dekoratora do pomiaru czasu to kolejna opcja. ( Źródło ) Zaletą tej metody jest to, że definiujesz timer raz i używasz go z prostą dodatkową linią dla każdej funkcji.

Najpierw zdefiniuj timerdekoratora:

import functools
import time

def timer(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.perf_counter()
        value = func(*args, **kwargs)
        end_time = time.perf_counter()
        run_time = end_time - start_time
        print("Finished {} in {} secs".format(repr(func.__name__), round(run_time, 3)))
        return value

    return wrapper

Następnie użyj dekoratora podczas definiowania funkcji:

@timer
def doubled_and_add(num):
    res = sum([i*2 for i in range(num)])
    print("Result : {}".format(res))

Spróbujmy:

doubled_and_add(100000)
doubled_and_add(1000000)

Wynik:

Result : 9999900000
Finished 'doubled_and_add' in 0.0119 secs
Result : 999999000000
Finished 'doubled_and_add' in 0.0897 secs

Uwaga: nie jestem pewien, dlaczego używać time.perf_counterzamiast time.time. Komentarze są mile widziane.


1

Możesz też spróbować tego:

from time import perf_counter

t0 = perf_counter()

...

t1 = perf_counter()
time_taken = t1 - t0
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.