Einfache Methode zum Messen der Ausführungszeit von Zellen in einem Python-Notizbuch


181

Ich möchte die Zeit, die für die Ausführung der Zelle aufgewendet wird, zusätzlich zur ursprünglichen Ausgabe der Zelle erhalten.

Zu diesem Zweck habe ich es versucht, %%timeit -r1 -n1aber die in cell definierte Variable wird nicht verfügbar gemacht.

%%time funktioniert für Zellen, die nur 1 Anweisung enthalten.

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

Was ist der beste Weg, um es zu tun?

Aktualisieren

Ich benutze Execute Time in Nbextension schon seit einiger Zeit. Es ist großartig.


3
Müssen Sie die Anzeige des Wertes wirklich zeitlich festlegen? Warum nicht einfach die xAnzeigezeile in die nächste Zelle setzen?
Dbliss

Warum nicht eine Antwort annehmen?
Raratiru

Antworten:


47

Verwenden Sie Zellmagie und dieses Projekt auf Github von Phillip Cloud:

Laden Sie es, indem Sie es oben in Ihr Notizbuch einfügen, oder fügen Sie es in Ihre Konfigurationsdatei ein, wenn Sie es immer standardmäßig laden möchten:

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

Wenn geladen, enthält jede Ausgabe der nachfolgenden Zellenausführung die Zeit in Minuten und Sekunden, die für die Ausführung benötigt wurde.


15
Dies funktioniert nicht mehr, da% install_ext veraltet ist. Gibt es eine Alternative?
eyeApps LLC

13
Es gibt eine Pull-Anfrage, die dieses Problem behebt ( github.com/cpcloud/ipython-autotime/pull/5 ), dann können Sie versuchenpip install ipython-autotime
x0s

13
Funktioniert jetzt %%timeauch wenn die letzte Aussage nicht ist print.
rhaps0dy

439

Die einzige Möglichkeit, dieses Problem zu lösen, besteht darin, die letzte Anweisung mit print auszuführen.

Vergessen Sie nicht, dass Zellmagie mit %%und Linienmagie mit beginnt %.

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

Beachten Sie, dass Änderungen, die in der Zelle vorgenommen werden, in den nächsten Zellen nicht berücksichtigt werden. Dies ist bei einer Pipeline nicht intuitiv: ein Beispiel


4
Jetzt funktioniert %% time auch dann, wenn die letzte Anweisung nicht gedruckt wird, wie @ rhaps0dy oben ausgeführt hat.
Nealmcb

1
display (res) funktioniert auch und ist die bevorzugte Lösung, wenn versucht wird, einen Pandas-Datenrahmen oder etwas anderes anzuzeigen, das eine stilisierte Ausgabe erfordert.
Dshefman

@dshefman Ja, das ist richtig und macht es auch für Databricks / Spark-Notebooks leicht tragbar.
Technazi

Ist es nicht ein Problem, wenn wir die 1. Zelle implementieren %%timeund a=1die 2. Zelle nicht weiß, was aist?
Jason

2
Zu Ihrer Information. Ich fand heraus, dass Variablen in der getesteten Zelle jetzt in den nächsten Zellen berücksichtigt werden. (20/02/2020) - Fei
Fei Yao


43

Eine einfachere Möglichkeit ist die Verwendung des ExecuteTime-Plugins im Paket jupyter_contrib_nbextensions.

pip install jupyter_contrib_nbextensions
jupyter contrib nbextension install --user
jupyter nbextension enable execute_time/ExecuteTime

5
Dies ist die am meisten unterschätzte Antwort!
DaveR

1
für jemanden, der durch die Antworten Meer taucht: Dies ist die eine, installieren Sie es einfach und dann sehen Sie die Ausführungszeit auf jeder Zelle in einem schönen Format
El pocho la pantera

14

Ich habe einfach %%timeam Anfang der Zelle hinzugefügt und die Zeit bekommen. Sie können dasselbe in Jupyter Spark-Cluster- / virtuellen Umgebungen verwenden, die dasselbe verwenden. Fügen Sie einfach %%timeoben in der Zelle hinzu und Sie erhalten die Ausgabe. Bei einem Spark-Cluster mit Jupyter habe ich oben in der Zelle hinzugefügt und die folgende Ausgabe erhalten: -

[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

Führt dies den Zellencode als Standard-Nr. mal und nimmt dann den Durchschnitt? Und was ist mit der ersten Anweisung als "Setup-Code"?
Amsquareb

12
import time
start = time.time()
"the code you want to test stays here"
end = time.time()
print(end - start)


9

Das ist nicht gerade schön, aber ohne zusätzliche Software

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

Dann können Sie es wie folgt ausführen:

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

% 49999995000000
% runtime: 0:00:00.338492

7

Manchmal ist die Formatierung in einer Zelle bei der Verwendung anders print(res), aber jupyter / ipython wird mit a geliefert display. Unten sehen Sie ein Beispiel für den Formatierungsunterschied mit Pandas.

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

Die displayAnweisung kann die Formatierung beibehalten. Bildschirmfoto


Führt dies den Zellencode als Standard-Nr. mal und nimmt dann den Durchschnitt? Und was ist mit der ersten Anweisung als "Setup-Code"?
Amsquareb

2

Vielleicht möchten Sie auch einen Blick auf Pythons magischen Profiling-Befehl werfen, %prunder so etwas wie -

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

dann

%prun sum_of_lists(1000000)

wird zurückkehren

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}

Ich finde es nützlich, wenn ich mit großen Codestücken arbeite.


2

Wenn in Schwierigkeiten, was bedeutet was:

?%timeit oder ??timeit

Um die Details zu erhalten:

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.

1

Wenn Sie die Ausführungszeit von Wandzellen hier drucken möchten, ist dies ein Trick

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

Stellen Sie hier jedoch sicher, dass die %% -Zeit eine magische Funktion ist. Fügen Sie sie daher in die erste Zeile Ihres Codes ein .

Wenn Sie es nach einer Zeile Ihres Codes einfügen, wird es Ihnen einen Verwendungsfehler geben und nicht funktionieren.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.