Un moyen simple de mesurer le temps d'exécution des cellules dans le notebook ipython

182

Je voudrais obtenir le temps passé sur l'exécution de la cellule en plus de la sortie d'origine de la cellule.

À cette fin, j'ai essayé %%timeit -r1 -n1mais cela n'expose pas la variable définie dans la cellule.

%%time fonctionne pour la cellule qui ne contient qu'une seule instruction.

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

Quelle est la meilleure façon de le faire?

Mettre à jour

J'utilise Execute Time dans Nbextension depuis un certain temps maintenant. C'est super.

colincroc
la source
3
avez-vous vraiment besoin de chronométrer l'affichage de la valeur? pourquoi ne pas simplement mettre la xligne d'affichage dans la cellule suivante?
dbliss
Pourquoi ne pas accepter une réponse?
raratiru

Réponses:

46

Utilisez la magie cellulaire et ce projet sur github par Phillip Cloud:

Chargez-le en le mettant en haut de votre notebook ou mettez-le dans votre fichier de configuration si vous voulez toujours le charger par défaut:

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

S'il est chargé, chaque sortie de l'exécution de cellule suivante inclura le temps en minutes et en secondes nécessaire pour l'exécuter.

Philipp Schwarz
la source
15
cela ne fonctionne plus, car% install_ext est obsolète. Y a-t-il une alternative?
eyeApps LLC
13
Il y a une Pull Request traitant de ce problème ( github.com/cpcloud/ipython-autotime/pull/5 ) alors vous pouvez essayerpip install ipython-autotime
x0s
13
Fonctionne maintenant %%timemême lorsque la dernière instruction ne l'est pas print.
rhaps0dy du
444

Le seul moyen que j'ai trouvé pour surmonter ce problème est d'exécuter la dernière instruction avec print.

N'oubliez pas que la magie cellulaire commence par %%et la magie des lignes commence par %.

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

Notez que les modifications effectuées à l'intérieur de la cellule ne sont pas prises en compte dans les cellules suivantes, ce qui est contre-intuitif lorsqu'il y a un pipeline: un exemple

Salvador Dali
la source
5
Désormais, %% time fonctionne même lorsque la dernière instruction n'est pas imprimée, comme @ rhaps0dy l'a souligné ci-dessus.
nealmcb
1
display (res) fonctionne également et est la solution préférée lorsque vous essayez d'afficher une trame de données pandas ou quelque chose d'autre qui nécessite une sortie stylisée.
dshefman
@dshefman Oui, c'est correct et le rend facilement portable pour les blocs-notes databricks / spark.
technazi
N'est-ce pas un problème lorsque nous implémentons la 1ère cellule %%timeet a=1que la 2ème cellule ne sait pas ce que ac'est?
Jason
3
FYI. J'ai constaté que les variables de la cellule testée sont désormais prises en compte dans les cellules suivantes. (20/02/2020) - Fei
Fei Yao
44

Un moyen plus simple consiste à utiliser le plugin ExecuteTime dans le package jupyter_contrib_nbextensions.

pip install jupyter_contrib_nbextensions
jupyter contrib nbextension install --user
jupyter nbextension enable execute_time/ExecuteTime
vForce
la source
6
C'est la réponse la plus sous-estimée!
DaveR
2
à quelqu'un qui plonge dans la mer des réponses: c'est celui-ci, installez-le simplement et vous verrez le temps d'exécution sur chaque cellule dans un bon format
El pocho la pantera
14

J'ai simplement ajouté %%timeau début de la cellule et j'ai obtenu l'heure. Vous pouvez utiliser le même sur le cluster Jupyter Spark / l'environnement virtuel en utilisant le même. Ajoutez simplement %%timeen haut de la cellule et vous obtiendrez la sortie. Sur le cluster d'étincelles utilisant Jupyter, j'ai ajouté en haut de la cellule et j'ai obtenu une sortie comme ci-dessous: -

[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
la source
Est-ce que cela exécute le code de cellule un non par défaut. de fois et prend ensuite la moyenne? Et qu'en est-il de la première déclaration en tant que «code de configuration»?
amsquareb le
14
import time
start = time.time()
"the code you want to test stays here"
end = time.time()
print(end - start)
mina
la source
1
Parfait. C'est trop compliqué de préserver l'objet de %% timeit et de l'utiliser dans la cellule suivante
Paul
9

Ce n'est pas vraiment beau mais sans logiciel supplémentaire

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

Ensuite, vous pouvez l'exécuter comme:

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

% 49999995000000
% runtime: 0:00:00.338492
eafit
la source
7

Parfois, le formatage est différent dans une cellule lors de l'utilisation print(res), mais jupyter / ipython est livré avec un fichier display. Voir un exemple de la différence de formatage à l'aide de pandas ci-dessous.

%%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' displayinstruction peut conserver la mise en forme. capture d'écran

Blehman
la source
Est-ce que cela exécute le code de cellule un non par défaut. de fois et prend ensuite la moyenne? Et qu'en est-il de la première déclaration en tant que «code de configuration»?
amsquareb le
2

vous pouvez également consulter la commande magique de profilage de python %prunqui donne quelque chose comme -

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

puis

%prun sum_of_lists(1000000)

reviendra

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}

Je trouve cela utile lorsque vous travaillez avec de gros morceaux de code.

Markroxor
la source
2

En cas de problème, ce qui signifie quoi:

?%timeit ou ??timeit

Pour obtenir les détails:

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
la source
1

Si vous souhaitez imprimer le temps d'exécution de la cellule murale, voici une astuce, utilisez

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

mais ici assurez-vous que le temps %% est une fonction magique, alors mettez-le en première ligne dans votre code .

si vous le mettez après une ligne de votre code, cela vous donnera une erreur d'utilisation et ne fonctionnera pas.

nemish zalavadiya neel
la source