Jeśli naprawdę chcesz mieć bezpośredni odpowiednik, po prostu zadzwoń, tic = time.time()a toc = time.time(), print toc-tic, 'sec Elapsed'jak powiedzieli ludzie poniżej, timeitjest jednak bardziej wytrzymały.
Joe Kington
Wydaje się, że lepsze wyniki uzyskuję stosując podejście @ JoeKington w połączeniu z timeit.default_timer (), jak na przykład:, tic = timeit.default_timer(); (U,S,V) = np.linalg.svd(A); toc = timeit.default_timer()then print toc-tic.
littleO
1
Biblioteka pytictoc wydaje się najdobitniejsza, składnia jest nawet nieco schludniejsza niż poniżej ttictoc. pypi.org/project/pytictoc
FlorianH
Odpowiedzi:
172
Poza timeittym, o czym wspomniał ThiefMaster, prostym sposobem na to jest po prostu (po imporcie time):
t = time.time()# do stuff
elapsed = time.time()- t
@eat: Z całym szacunkiem się nie zgadzam. Ludzie od zawsze używali timepolecenia unix do mierzenia czasu wykonywania programów, a ta metoda powiela to w kodzie Pythona. Nie widzę w tym nic złego, o ile jest to właściwe narzędzie do pracy. timeitnie zawsze tak jest, a profiler jest znacznie cięższym rozwiązaniem dla większości potrzeb
Eli Bendersky
4
Na ostatnią linię zasugerowałbym print 'Elapsed: %.2f seconds % (time.time() - self.tstart)'. Trudno to zrozumieć bez% .2f. Dzięki za świetny pomysł.
Can Kavaklıoğlu
4
Na pierwszy rzut oka wygląda to bardzo wygodnie, ale w praktyce wymaga wcięcia bloku kodu, który chcemy w czasie, co może być dość niewygodne w zależności od długości bloku kodu i wybranego edytora. Wciąż eleganckie rozwiązanie, które zachowuje się poprawnie w przypadku użytkowania zagnieżdżonego.
Stefan
1
Myślę, że chcesz elapsed = t - time.time(), zamiast elapsed = time.time() - t. W tym ostatnim upłynął będzie ujemny. Zaproponowałem tę zmianę jako edycję.
rysqui
3
@rysqui - Czy aktualna godzina nie jest zawsze większa niż poprzednia ? Myślę, że elapsed = time.time() - tjest to forma, która zawsze daje wartość dodatnią.
Scott Smith
32
Miałem to samo pytanie, kiedy migrowałem do Pythona z Matlab. Z pomocą tego wątku udało mi się skonstruować dokładny odpowiednik Matlaba tic()i toc()funkcji. Po prostu wstaw następujący kod u góry skryptu.
import time
defTicTocGenerator():# Generator that returns time differences
ti =0# initial time
tf = time.time()# final timewhileTrue:
ti = tf
tf = time.time()yield tf-ti # returns the time differenceTicToc=TicTocGenerator()# create an instance of the TicTocGen generator# This will be the main function through which we define both tic() and toc()def toc(tempBool=True):# Prints the time difference yielded by generator instance TicToc
tempTimeInterval =next(TicToc)if tempBool:print("Elapsed time: %f seconds.\n"%tempTimeInterval )def tic():# Records a time in TicToc, marks the beginning of a time interval
toc(False)
Otóż to! Teraz jesteśmy gotowi do pełnego wykorzystania tic()i toc()tak jak w Matlabie. Na przykład
W rzeczywistości jest to bardziej wszechstronne niż wbudowane funkcje Matlab. Tutaj możesz utworzyć kolejną instancję, TicTocGeneratoraby śledzić wiele operacji lub po prostu inaczej mierzyć czas. Na przykład, podczas odmierzania czasu skryptu, możemy teraz określić czas dla każdego fragmentu skryptu oddzielnie, a także dla całego skryptu. (Podam konkretny przykład)
TicToc2=TicTocGenerator()# create another instance of the TicTocGen generatordef toc2(tempBool=True):# Prints the time difference yielded by generator instance TicToc2
tempTimeInterval =next(TicToc2)if tempBool:print("Elapsed time 2: %f seconds.\n"%tempTimeInterval )def tic2():# Records a time in TicToc2, marks the beginning of a time interval
toc2(False)
Teraz powinieneś być w stanie zmierzyć czas w dwóch osobnych rzeczach: W poniższym przykładzie oddzielnie mierzymy czas dla całego skryptu i części skryptu.
Absolutnie najlepszym analogiem tic i toc byłoby po prostu zdefiniowanie ich w Pythonie.
def tic():#Homemade version of matlab tic and toc functionsimport time
global startTime_for_tictoc
startTime_for_tictoc = time.time()def toc():import time
if'startTime_for_tictoc'in globals():print"Elapsed time is "+ str(time.time()- startTime_for_tictoc)+" seconds."else:print"Toc: start time not set"
Nie będzie to działać poprawnie w przypadku zagnieżdżonego użycia tici toc, które obsługuje Matlab. Wymagane byłoby trochę więcej wyrafinowania.
Stefan
2
Zaimplementowałem podobne funkcje we własnym kodzie, gdy potrzebowałem podstawowego timingu. Chciałbym jednak usunąć import timezewnętrzną stronę obu funkcji, ponieważ może to zająć trochę czasu.
Bas Swinckels
Jeśli upierasz się przy używaniu tej techniki i potrzebujesz jej do obsługi zagnieżdżonych tic / toc, zrób globalną listę i pozwól jej ticpushować i tocwyskakiwać z niej.
Ahmed Fasih
1
Czytałem też gdzie indziej, że timeit.default_timer()jest to lepsze niż time.time()ponieważ time.clock()może być bardziej odpowiednie w zależności od systemu operacyjnego
Miguel,
@AhmedFasih Tak właśnie działa moja odpowiedź, chociaż można by poprawić więcej.
antonimmo
15
Zazwyczaj ipython na %time, %timeit, %prunoraz %lprun(jeśli jest line_profilerzainstalowany) spełniają moje potrzeby profilowania całkiem dobrze. Jednak przypadek użycia tic-tocfunkcji-like pojawił się, gdy próbowałem profilować obliczenia, które były interaktywnie sterowane, tj. Przez ruch myszy użytkownika w GUI. Czułem, że spamowanie tici spamowanie tocw źródłach podczas interaktywnego testowania byłoby najszybszym sposobem na ujawnienie wąskich gardeł. Poszedłem z Timerklasą Eli Bendersky'ego , ale nie byłem w pełni zadowolony, ponieważ wymagało to zmiany wcięcia mojego kodu, co może być niewygodne w niektórych edytorach i dezorientuje system kontroli wersji. Ponadto może zaistnieć potrzeba pomiaru czasu między punktami w różnych funkcjach, które nie działałyby zwithkomunikat. Po wypróbowaniu dużej ilości sprytu w Pythonie, oto proste rozwiązanie, które według mnie działa najlepiej:
from time import time
_tstart_stack =[]def tic():
_tstart_stack.append(time())def toc(fmt="Elapsed: %s s"):print fmt %(time()- _tstart_stack.pop())
Ponieważ działa to poprzez przesuwanie czasów rozpoczęcia na stosie, będzie działać poprawnie na wielu poziomach ticsi tocs. Pozwala również zmienić ciąg formatu tocinstrukcji, aby wyświetlić dodatkowe informacje, które podobały mi się w Timerklasie Eli .
Z jakiegoś powodu martwiłem się o narzuty związane z czystą implementacją Pythona, więc przetestowałem również moduł rozszerzenia C:
To jest dla MacOSX i pominąłem kod, aby sprawdzić, czy lvljest poza zakresem dla zwięzłości. Chociaż tictoc.res()zapewnia rozdzielczość około 50 nanosekund w moim systemie, odkryłem, że jitter pomiaru dowolnej instrukcji Pythona z łatwością mieści się w zakresie mikrosekund (i znacznie więcej, gdy jest używany z IPythona). W tym momencie narzut implementacji Pythona staje się pomijalny, dzięki czemu można go używać z takim samym zaufaniem jak implementacja C.
Okazało się, że użyteczność metody tic-toc-podejścia jest praktycznie ograniczona do bloków kodu, których wykonanie zajmuje więcej niż 10 mikrosekund. Poniżej, timeitaby uzyskać wierny pomiar, wymagane są strategie uśredniania, takie jak w .
Właśnie utworzyłem moduł [tictoc.py] do tworzenia zagnieżdżonych tików, co robi Matlab.
from time import time
tics =[]def tic():
tics.append(time())def toc():if len(tics)==0:returnNoneelse:return time()-tics.pop()
I to działa w ten sposób:
from tictoc import tic, toc
# This keeps track of the whole process
tic()# Timing a small portion of code (maybe a loop)
tic()# -- Nested code here --# End
toc()# This returns the elapse time (in seconds) since the last invocation of tic()
toc()# This does the same for the first tic()
Muszę cię ostrzec, że może to nie zachowywać się zgodnie z oczekiwaniami, gdy jest używane jednocześnie przez więcej niż 1 moduł, ponieważ moduły (AFAIK) zachowują się jak pojedyncze.
antonimmo
3
Przyjrzyj się timeitmodułowi. Nie jest to tak naprawdę równoważne, ale jeśli kod, który chcesz mierzyć czas, znajduje się wewnątrz funkcji, możesz go łatwo użyć.
Można to również zrobić za pomocą opakowania. Bardzo ogólny sposób na trzymanie czasu.
Opakowanie w tym przykładowym kodzie otacza dowolną funkcję i wyświetla ilość czasu potrzebną do wykonania funkcji:
def timethis(f):import time
def wrapped(*args,**kwargs):
start = time.time()
r = f(*args,**kwargs)print"Executing {0} took {1} seconds".format(f.func_name, time.time()-start)return r
return wrapped
@timethisdef thistakestime():for x in range(10000000):pass
thistakestime()
Funkcja owijania, timethis, nazywana jest dekoratorem. Trochę bardziej szczegółowe wyjaśnienie, tutaj: medium.com/pythonhive/…
Mircea
1
Zmieniłem trochę odpowiedź @Eli Bendersky, aby użyć ctor __init__()i dtor __del__()do pomiaru czasu, aby można było z niego wygodniej korzystać bez wcięcia oryginalnego kodu:
Problem z tą implementacją polega na tym, że timernie jest ona usuwana po ostatnim wywołaniu, jeśli po forpętli występuje inny kod . Aby uzyskać ostatnią wartość timera, należy usunąć lub nadpisać timerpo forpętli, na przykład poprzez timer = None.
bastelflp
1
@bastelflp Właśnie sobie uświadomiłem, że źle zrozumiałem, co masz na myśli ... Twoja sugestia została teraz uwzględniona w kodzie. Dzięki.
Podobnie jak Eli, może być używany jako menedżer kontekstu:
import time
withTimer('Count'):for i in range(0,10_000_000):pass
Wynik:
[Count]Elapsed:0.27 seconds
Zaktualizowałem go również, aby drukować zgłaszane jednostki czasu (sekundy) i zmniejszać liczbę cyfr zgodnie z sugestią Can, a także z opcją dołączania do pliku dziennika. Aby korzystać z funkcji rejestrowania, musisz zaimportować datę i godzinę:
import time
import datetime
withTimer('Count','log.txt'):for i in range(0,10_000_000):pass
możesz po prostu użyć tic(), toc()a gniazdo nich jak w Matlab
Alternatywnie, można je nazwać: tic(1), toc(1)lub tic('very-important-block'), toc('very-important-block')i timery z różnymi nazwami nie będzie kolidować
zaimportowanie ich w ten sposób zapobiega zakłóceniom między modułami z nich korzystającymi.
(tutaj toc nie drukuje czasu, który upłynął, ale zwraca go).
tic = time.time()
atoc = time.time()
,print toc-tic, 'sec Elapsed'
jak powiedzieli ludzie poniżej,timeit
jest jednak bardziej wytrzymały.tic = timeit.default_timer(); (U,S,V) = np.linalg.svd(A); toc = timeit.default_timer()
thenprint toc-tic
.Odpowiedzi:
Poza
timeit
tym, o czym wspomniał ThiefMaster, prostym sposobem na to jest po prostu (po imporcietime
):Mam klasę pomocniczą, której lubię używać:
Może być używany jako menedżer kontekstu:
Czasami uważam tę technikę za wygodniejszą niż
timeit
- wszystko zależy od tego, co chcesz zmierzyć.źródło
time
polecenia unix do mierzenia czasu wykonywania programów, a ta metoda powiela to w kodzie Pythona. Nie widzę w tym nic złego, o ile jest to właściwe narzędzie do pracy.timeit
nie zawsze tak jest, a profiler jest znacznie cięższym rozwiązaniem dla większości potrzebprint 'Elapsed: %.2f seconds % (time.time() - self.tstart)'
. Trudno to zrozumieć bez% .2f. Dzięki za świetny pomysł.elapsed = t - time.time()
, zamiastelapsed = time.time() - t
. W tym ostatnim upłynął będzie ujemny. Zaproponowałem tę zmianę jako edycję.elapsed = time.time() - t
jest to forma, która zawsze daje wartość dodatnią.Miałem to samo pytanie, kiedy migrowałem do Pythona z Matlab. Z pomocą tego wątku udało mi się skonstruować dokładny odpowiednik Matlaba
tic()
itoc()
funkcji. Po prostu wstaw następujący kod u góry skryptu.Otóż to! Teraz jesteśmy gotowi do pełnego wykorzystania
tic()
itoc()
tak jak w Matlabie. Na przykładW rzeczywistości jest to bardziej wszechstronne niż wbudowane funkcje Matlab. Tutaj możesz utworzyć kolejną instancję,
TicTocGenerator
aby śledzić wiele operacji lub po prostu inaczej mierzyć czas. Na przykład, podczas odmierzania czasu skryptu, możemy teraz określić czas dla każdego fragmentu skryptu oddzielnie, a także dla całego skryptu. (Podam konkretny przykład)Teraz powinieneś być w stanie zmierzyć czas w dwóch osobnych rzeczach: W poniższym przykładzie oddzielnie mierzymy czas dla całego skryptu i części skryptu.
Właściwie nie musisz nawet używać za
tic()
każdym razem. Jeśli masz serię poleceń, które chcesz mierzyć czas, możesz napisaćMam nadzieję, że jest to pomocne.
źródło
Absolutnie najlepszym analogiem tic i toc byłoby po prostu zdefiniowanie ich w Pythonie.
Następnie możesz ich użyć jako:
źródło
tic
itoc
, które obsługuje Matlab. Wymagane byłoby trochę więcej wyrafinowania.import time
zewnętrzną stronę obu funkcji, ponieważ może to zająć trochę czasu.tic
pushować itoc
wyskakiwać z niej.timeit.default_timer()
jest to lepsze niżtime.time()
ponieważtime.clock()
może być bardziej odpowiednie w zależności od systemu operacyjnegoZazwyczaj ipython na
%time
,%timeit
,%prun
oraz%lprun
(jeśli jestline_profiler
zainstalowany) spełniają moje potrzeby profilowania całkiem dobrze. Jednak przypadek użyciatic-toc
funkcji-like pojawił się, gdy próbowałem profilować obliczenia, które były interaktywnie sterowane, tj. Przez ruch myszy użytkownika w GUI. Czułem, że spamowanietic
i spamowanietoc
w źródłach podczas interaktywnego testowania byłoby najszybszym sposobem na ujawnienie wąskich gardeł. Poszedłem zTimer
klasą Eli Bendersky'ego , ale nie byłem w pełni zadowolony, ponieważ wymagało to zmiany wcięcia mojego kodu, co może być niewygodne w niektórych edytorach i dezorientuje system kontroli wersji. Ponadto może zaistnieć potrzeba pomiaru czasu między punktami w różnych funkcjach, które nie działałyby zwith
komunikat. Po wypróbowaniu dużej ilości sprytu w Pythonie, oto proste rozwiązanie, które według mnie działa najlepiej:Ponieważ działa to poprzez przesuwanie czasów rozpoczęcia na stosie, będzie działać poprawnie na wielu poziomach
tic
sitoc
s. Pozwala również zmienić ciąg formatutoc
instrukcji, aby wyświetlić dodatkowe informacje, które podobały mi się wTimer
klasie Eli .Z jakiegoś powodu martwiłem się o narzuty związane z czystą implementacją Pythona, więc przetestowałem również moduł rozszerzenia C:
To jest dla MacOSX i pominąłem kod, aby sprawdzić, czy
lvl
jest poza zakresem dla zwięzłości. Chociażtictoc.res()
zapewnia rozdzielczość około 50 nanosekund w moim systemie, odkryłem, że jitter pomiaru dowolnej instrukcji Pythona z łatwością mieści się w zakresie mikrosekund (i znacznie więcej, gdy jest używany z IPythona). W tym momencie narzut implementacji Pythona staje się pomijalny, dzięki czemu można go używać z takim samym zaufaniem jak implementacja C.Okazało się, że użyteczność metody
tic-toc
-podejścia jest praktycznie ograniczona do bloków kodu, których wykonanie zajmuje więcej niż 10 mikrosekund. Poniżej,timeit
aby uzyskać wierny pomiar, wymagane są strategie uśredniania, takie jak w .źródło
Możesz używać
tic
itoc
odttictoc
. Zainstaluj go zI po prostu zaimportuj je do swojego skryptu w następujący sposób
źródło
Właśnie utworzyłem moduł [tictoc.py] do tworzenia zagnieżdżonych tików, co robi Matlab.
I to działa w ten sposób:
Mam nadzieję, że to pomoże.
źródło
Przyjrzyj się
timeit
modułowi. Nie jest to tak naprawdę równoważne, ale jeśli kod, który chcesz mierzyć czas, znajduje się wewnątrz funkcji, możesz go łatwo użyć.źródło
timeit
najlepiej sprawdza się w testach porównawczych. Nie musi to być nawet pojedyncza funkcja, możesz przekazywać bardzo złożone instrukcje.W kodzie:
Zastrzeżenie: jestem autorem tej biblioteki.
źródło
Można to również zrobić za pomocą opakowania. Bardzo ogólny sposób na trzymanie czasu.
Opakowanie w tym przykładowym kodzie otacza dowolną funkcję i wyświetla ilość czasu potrzebną do wykonania funkcji:
źródło
Zmieniłem trochę odpowiedź @Eli Bendersky, aby użyć ctor
__init__()
i dtor__del__()
do pomiaru czasu, aby można było z niego wygodniej korzystać bez wcięcia oryginalnego kodu:Aby użyć, po prostu umieść Timer („blahblah”) na początku jakiegoś lokalnego zakresu. Upływający czas zostanie wydrukowany na końcu zakresu:
Drukuje:
źródło
timer
nie jest ona usuwana po ostatnim wywołaniu, jeśli pofor
pętli występuje inny kod . Aby uzyskać ostatnią wartość timera, należy usunąć lub nadpisaćtimer
pofor
pętli, na przykład poprzeztimer = None
.Aktualizacja odpowiedzi Eli do Pythona 3:
Podobnie jak Eli, może być używany jako menedżer kontekstu:
Wynik:
Zaktualizowałem go również, aby drukować zgłaszane jednostki czasu (sekundy) i zmniejszać liczbę cyfr zgodnie z sugestią Can, a także z opcją dołączania do pliku dziennika. Aby korzystać z funkcji rejestrowania, musisz zaimportować datę i godzinę:
źródło
Opierając się na odpowiedziach Stefana i antonimmo, skończyło się umieszczaniem
w
utils.py
module i używam go z plikiemTą drogą
tic()
,toc()
a gniazdo nich jak w Matlabtic(1)
,toc(1)
lubtic('very-important-block')
,toc('very-important-block')
i timery z różnymi nazwami nie będzie kolidować(tutaj toc nie drukuje czasu, który upłynął, ale zwraca go).
źródło