Modo semplice per misurare i tempi di esecuzione delle celle nel notebook ipython


182

Vorrei ottenere il tempo speso per l'esecuzione della cella oltre all'output originale dalla cella.

A tal fine, ho provato %%timeit -r1 -n1ma non espone la variabile definita all'interno della cella.

%%time funziona per la cella che contiene solo 1 istruzione.

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

Qual è il modo migliore per farlo?

Aggiornare

Sto usando Execute Time in Nbextension ormai da un po 'di tempo. È grande.


3
hai davvero bisogno di cronometrare la visualizzazione del valore? perché non mettere semplicemente la xriga del display nella cella successiva?
dbliss,

Perché non accettare una risposta?
raratiru,

Risposte:


46

Usa la magia delle cellule e questo progetto su github di Phillip Cloud:

Caricalo inserendolo nella parte superiore del notebook o inserendolo nel file di configurazione se si desidera sempre caricarlo per impostazione predefinita:

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

Se caricato, ogni output della successiva esecuzione della cella includerà il tempo in minuti e secondi impiegato per eseguirlo.


15
questo non funziona più, poiché% install_ext è obsoleto. C'è un'alternativa?
eyeApps LLC,

13
C'è una richiesta pull che risolve questo problema ( github.com/cpcloud/ipython-autotime/pull/5 ) quindi puoi provarepip install ipython-autotime
x0s

13
Ora %%timefunziona anche quando l'ultima affermazione non lo è print.
rhaps0dy,

444

L'unico modo in cui ho scoperto di superare questo problema è eseguendo l'ultima istruzione con print.

Non dimenticare che la magia cellulare inizia con %%e inizia la magia linea %.

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

Si noti che eventuali modifiche apportate all'interno della cella non vengono prese in considerazione nelle celle successive, qualcosa che è contro intuitivo quando c'è una pipeline: un esempio


5
Ora %% time funziona anche quando l'ultima istruzione non viene stampata, come sottolineato da @ rhaps0dy sopra.
nealmcb,

1
display (res) funziona anche ed è la soluzione preferita quando si tenta di visualizzare un frame di dati panda o qualcos'altro che richiede un output stilizzato.
Dshefman,

@dshefman Sì, è corretto e lo rende facilmente trasportabile anche per databrick / spark notebook.
technazi,

Non è un problema quando implementiamo la cellula prima %%timee a=1, ma la seconda cella non sa cosa aè?
Jason,

3
FYI. Ho scoperto che le variabili nella cella testata sono ora prese in considerazione nelle celle successive. (20/02/2020) - Fei
Fei Yao


44

Un modo più semplice è utilizzare il plug-in ExecuteTime nel pacchetto jupyter_contrib_nbextensions.

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

6
Questa è la risposta più sottovalutata!
DaveR,

2
a qualcuno che si tuffa attraverso le risposte del mare: questo è quello, basta installarlo e poi vedrai i tempi di esecuzione su ogni cella in un bel formato
El pocho la pantera

14

Ho semplicemente aggiunto %%timeall'inizio della cella e ho ottenuto il tempo. È possibile utilizzare lo stesso nel cluster / ambiente virtuale Jupyter Spark usando lo stesso. Basta aggiungere %%timenella parte superiore della cella e otterrai l'output. Su spark cluster usando Jupyter, ho aggiunto nella parte superiore della cella e ho ottenuto l'output come di seguito: -

[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

Questo esegue il codice cella un numero predefinito. di volte e poi prende la media? E la prima affermazione come "codice di installazione"?
amsquareb,

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

1
Perfetto. È troppo fastidioso preservare l'oggetto da %% timeit e usarlo nella cella successiva
Paul


9

Questo non è esattamente bello ma senza software aggiuntivo

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

Quindi puoi eseguirlo come:

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

% 49999995000000
% runtime: 0:00:00.338492

7

A volte la formattazione è diversa in una cella quando si utilizza print(res), ma jupyter / ipython viene fornito con a display. Vedi un esempio della differenza di formattazione usando i panda di seguito.

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

L' displayistruzione può preservare la formattazione. immagine dello schermo


Questo esegue il codice cella un numero predefinito. di volte e poi prende la media? E la prima affermazione come "codice di installazione"?
amsquareb,

2

potresti anche voler dare un'occhiata al comando magico di profilazione di Python %prunche dà qualcosa di simile -

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

poi

%prun sum_of_lists(1000000)

sarà di ritorno

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}

Lo trovo utile quando si lavora con grossi blocchi di codice.


2

In caso di problemi cosa significa cosa:

?%timeit o ??timeit

Per ottenere i dettagli:

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

Se vuoi stampare il tempo di esecuzione delle celle a muro qui è un trucco, usa

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

ma qui assicurati che il %% time sia una funzione magica, quindi mettilo alla prima riga nel tuo codice .

se lo metti dopo una riga del tuo codice ti darà un errore di utilizzo e non funzionerà.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.