Prosty sposób na pomiar czasu wykonania komórki w notebooku ipython

182

Chciałbym otrzymać czas spędzony na wykonaniu komórki oprócz oryginalnego wyniku z komórki.

W tym celu próbowałem, %%timeit -r1 -n1ale nie ujawnia to zmiennej zdefiniowanej w komórce.

%%time działa dla komórki, która zawiera tylko 1 instrukcję.

In[1]: %%time
       1
CPU times: user 4 µs, sys: 0 ns, total: 4 µs
Wall time: 5.96 µs
Out[1]: 1

In[2]: %%time
       # Notice there is no out result in this case.
       x = 1
       x
CPU times: user 3 µs, sys: 0 ns, total: 3 µs
Wall time: 5.96 µs

Jak najlepiej to zrobić?

Aktualizacja

Używam czasu wykonania w Nbextension już od jakiegoś czasu. To jest wspaniałe.

colinfang
źródło
3
czy naprawdę potrzebujesz mierzyć czas wyświetlania wartości? dlaczego po prostu nie umieścić xlinii wyświetlania w następnej komórce?
dbliss
Dlaczego nie przyjąć odpowiedzi?
raratiru

Odpowiedzi:

46

Użyj magii komórek i tego projektu na github autorstwa Phillip Cloud:

Załaduj go, umieszczając go na górze notebooka lub umieść w pliku konfiguracyjnym, jeśli zawsze chcesz go ładować domyślnie:

%install_ext https://raw.github.com/cpcloud/ipython-autotime/master/autotime.py
%load_ext autotime

Po załadowaniu każde wyjście kolejnego wykonania komórki będzie zawierało czas w minutach i sekundach potrzebny do jego wykonania.

Philipp Schwarz
źródło
15
to już nie działa, ponieważ% install_ext jest przestarzały. Czy jest alternatywa?
eyeApps LLC
13
Istnieje żądanie ściągnięcia dotyczące tego problemu ( github.com/cpcloud/ipython-autotime/pull/5 ), a następnie możesz spróbowaćpip install ipython-autotime
x0s
13
Teraz %%timedziała nawet wtedy, gdy ostatnia instrukcja nie jest print.
rhaps0dy
444

Jedynym sposobem rozwiązania tego problemu jest wykonanie ostatniej instrukcji za pomocą polecenia print.

Nie zapominaj, że magia komórek zaczyna się od, %%a magia linii zaczyna się od %.

%%time
clf = tree.DecisionTreeRegressor().fit(X_train, y_train)
res = clf.predict(X_test)
print(res)

Zwróć uwagę, że wszelkie zmiany wprowadzone w komórce nie są brane pod uwagę w następnych komórkach, co jest sprzeczne z intuicją, gdy istnieje potok: przykład

Salvador Dali
źródło
5
Teraz %% czas działa nawet wtedy, gdy ostatnia instrukcja nie jest wypisywana, jak @ rhaps0dy wskazał powyżej.
nealmcb
1
display (res) działa również i jest preferowanym rozwiązaniem podczas próby wyświetlenia ramki danych pandy lub czegoś innego, co wymaga stylizowanego wyjścia.
dshefman
@dshefman Tak, to jest poprawne i ułatwia przenoszenie także dla notebooków databricks / spark.
technazi
Czy nie stanowi to problemu, gdy wdrażamy pierwszą komórkę, %%timea a=1druga komórka nie wie, co ato jest?
Jason
3
FYI. Stwierdziłem, że zmienne w testowanej komórce są teraz uwzględniane w kolejnych komórkach. (20.02.2020) - Fei
Fei Yao
44

Łatwiejszym sposobem jest użycie wtyczki ExecuteTime w pakiecie jupyter_contrib_nbextensions.

pip install jupyter_contrib_nbextensions
jupyter contrib nbextension install --user
jupyter nbextension enable execute_time/ExecuteTime
vForce
źródło
6
To najbardziej niedoceniana odpowiedź!
DaveR,
2
do kogoś nurkującego przez morze odpowiedzi: to ten, po prostu go zainstaluj, a wtedy zobaczysz czas wykonania na każdej komórce w ładnym formacie
El pocho la pantera
14

Po prostu dodałem %%timena początku komórki i uzyskałem czas. Możesz użyć tego samego w klastrze / środowisku wirtualnym Jupyter Spark przy użyciu tego samego. Po prostu dodaj %%timena górze komórki, a otrzymasz wynik. Na klastrze iskier za pomocą Jupytera dodałem do górnej części ogniwa i otrzymałem wyjście jak poniżej: -

[1]  %%time
     import pandas as pd
     from pyspark.ml import Pipeline
     from pyspark.ml.classification import LogisticRegression
     import numpy as np
     .... code ....

Output :-

CPU times: user 59.8 s, sys: 4.97 s, total: 1min 4s
Wall time: 1min 18s
Harry_pb
źródło
Czy to wykonuje kod komórki domyślny nr. razy, a następnie przyjmuje średnią? A co z pierwszym stwierdzeniem jako „kodem konfiguracji”?
amsquareb
14
import time
start = time.time()
"the code you want to test stays here"
end = time.time()
print(end - start)
mina
źródło
1
Idealny. Zachowanie obiektu od %% timeit i użycie go w następnej komórce jest zbyt kłopotliwe
Paul
9

To nie jest do końca piękne, ale bez dodatkowego oprogramowania

class timeit():
    from datetime import datetime
    def __enter__(self):
        self.tic = self.datetime.now()
    def __exit__(self, *args, **kwargs):
        print('runtime: {}'.format(self.datetime.now() - self.tic))

Następnie możesz uruchomić to tak:

with timeit():
    # your code, e.g., 
    print(sum(range(int(1e7))))

% 49999995000000
% runtime: 0:00:00.338492
eafit
źródło
7

Czasami formatowanie jest inne w komórce podczas używania print(res), ale jupyter / ipython zawiera rozszerzenie display. Zobacz przykład różnicy w formatowaniu przy użyciu pand poniżej.

%%time
import pandas as pd 
from IPython.display import display

df = pd.DataFrame({"col0":{"a":0,"b":0}
              ,"col1":{"a":1,"b":1}
              ,"col2":{"a":2,"b":2}
             })

#compare the following
print(df)
display(df)

Plik displayOświadczenie może zachować formatowanie. zrzut ekranu

blehman
źródło
Czy to wykonuje kod komórki domyślny nr. razy, a następnie przyjmuje średnią? A co z pierwszym stwierdzeniem jako „kodem konfiguracji”?
amsquareb
2

możesz również zajrzeć do magicznego polecenia profilowania w Pythonie, %prunktóre daje coś w rodzaju -

def sum_of_lists(N):
    total = 0
    for i in range(5):
        L = [j ^ (j >> i) for j in range(N)]
        total += sum(L)
    return total

następnie

%prun sum_of_lists(1000000)

wróci

14 function calls in 0.714 seconds  

Ordered by: internal time      

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    5    0.599    0.120    0.599    0.120 <ipython-input-19>:4(<listcomp>)
    5    0.064    0.013    0.064    0.013 {built-in method sum}
    1    0.036    0.036    0.699    0.699 <ipython-input-19>:1(sum_of_lists)
    1    0.014    0.014    0.714    0.714 <string>:1(<module>)
    1    0.000    0.000    0.714    0.714 {built-in method exec}

Uważam to za przydatne podczas pracy z dużymi fragmentami kodu.

markroxor
źródło
2

Kiedy masz kłopoty, co to znaczy:

?%timeit lub ??timeit

Aby uzyskać szczegółowe informacje:

Usage, in line mode:
  %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
or in cell mode:
  %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
  code
  code...

Time execution of a Python statement or expression using the timeit
module.  This function can be used both as a line and cell magic:

- In line mode you can time a single-line statement (though multiple
  ones can be chained with using semicolons).

- In cell mode, the statement in the first line is used as setup code
  (executed but not timed) and the body of the cell is timed.  The cell
  body has access to any variables created in the setup code.
prosti
źródło
1

Jeśli chcesz wydrukować czas wykonania komórki ściennej, jest to sztuczka, użyj

%%time
<--code goes here-->

ale tutaj upewnij się, że %% czas jest funkcją magiczną, więc umieść go w pierwszym wierszu kodu .

jeśli umieścisz go po jakimś wierszu kodu, spowoduje to błąd użytkowania i nie zadziała.

nemish zalavadiya neel
źródło