Manera simple de medir el tiempo de ejecución de la celda en el cuaderno ipython

182

Me gustaría obtener el tiempo dedicado a la ejecución de la celda además del resultado original de la celda.

Con este fin, lo intenté %%timeit -r1 -n1pero no expone la variable definida dentro de la celda.

%%time funciona para la celda que solo contiene 1 declaración.

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

¿Cuál es la mejor manera de hacerlo?

Actualizar

He estado usando Execute Time en Nbextension durante bastante tiempo. Eso es genial.

colinfang
fuente
3
¿realmente necesita cronometrar la visualización del valor? ¿Por qué no poner la xlínea de visualización en la celda siguiente?
dbliss
¿Por qué no aceptar una respuesta?
raratiru

Respuestas:

46

Utiliza la magia celular y este proyecto en github de Phillip Cloud:

Cárguelo poniéndolo en la parte superior de su computadora portátil o póngalo en su archivo de configuración si siempre desea cargarlo de manera predeterminada:

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

Si se carga, cada salida de la ejecución posterior de la celda incluirá el tiempo en minutos y segundos que tardó en ejecutarse.

Philipp Schwarz
fuente
15
esto ya no funciona, ya que% install_ext está en desuso. ¿Hay una alternativa?
eyeApps LLC
13
Hay una solicitud de extracción que aborda este problema ( github.com/cpcloud/ipython-autotime/pull/5 ), entonces puede intentarlopip install ipython-autotime
x0s
13
Ahora %%timefunciona incluso cuando la última declaración no lo es print.
rhaps0dy
444

La única forma en que encontré superar este problema es ejecutando la última declaración con print.

No olvides que la magia celular comienza con %%y la magia de línea comienza con %.

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

Tenga en cuenta que los cambios realizados dentro de la celda no se tienen en cuenta en las siguientes celdas, algo que es contrario a la intuición cuando hay una tubería: un ejemplo

Salvador Dalí
fuente
55
Ahora %% time funciona incluso cuando la última declaración no se imprime, como @ rhaps0dy señaló anteriormente.
nealmcb
1
display (res) también funciona y es la solución preferida cuando se intenta mostrar un marco de datos de pandas u otra cosa que requiera una salida estilizada.
dshefman
@dshefman Sí, eso es correcto y también es fácil de transportar para databricks / notebooks spark.
technazi
¿No es un problema cuando implementamos la primera celda %%timey a=1la segunda celda no sabe qué aes?
Jason
3
FYI. Descubrí que las variables en la celda probada ahora se tienen en cuenta en las siguientes celdas. (20/02/2020) - Fei
Fei Yao
44

Una forma más fácil es usar el complemento ExecuteTime en el paquete jupyter_contrib_nbextensions.

pip install jupyter_contrib_nbextensions
jupyter contrib nbextension install --user
jupyter nbextension enable execute_time/ExecuteTime
vForce
fuente
66
¡Esta es la respuesta más subestimada!
DaveR
2
para alguien que se sumerge en el mar de respuestas: este es el único, simplemente instálelo y luego verá el tiempo de ejecución en cada celda en un formato agradable
El pocho la pantera
14

Simplemente agregué %%timeal comienzo de la celda y obtuve el tiempo. Puede usar lo mismo en el clúster Jupyter Spark / entorno virtual con el mismo. Simplemente agregue %%timeen la parte superior de la celda y obtendrá la salida. En el grupo de chispas con Jupyter, agregué a la parte superior de la celda y obtuve la salida como a continuación:

[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
fuente
¿Esto ejecuta el código de celda un no predeterminado. de veces y luego toma el promedio? ¿Y qué hay de la primera declaración como 'código de configuración'?
amsquareb
14
import time
start = time.time()
"the code you want to test stays here"
end = time.time()
print(end - start)
mina
fuente
1
Perfecto. Es demasiado complicado preservar el objeto de %% timeit y usarlo en la próxima celda
Paul
9

Esto no es exactamente hermoso pero sin software adicional

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

Entonces puedes ejecutarlo como:

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

% 49999995000000
% runtime: 0:00:00.338492
eafit
fuente
7

A veces, el formato es diferente en una celda cuando se usa print(res), pero jupyter / ipython viene con un display. Vea un ejemplo de la diferencia de formato usando pandas a continuación.

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

La displaydeclaración puede preservar el formato. captura de pantalla

blehman
fuente
¿Esto ejecuta el código de celda un no predeterminado. de veces y luego toma el promedio? ¿Y qué hay de la primera declaración como 'código de configuración'?
amsquareb
2

También es posible que desee ver el comando mágico de creación de perfiles de Python %prunque proporciona algo como:

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

luego

%prun sum_of_lists(1000000)

volverá

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}

Me resulta útil cuando trabajo con grandes fragmentos de código.

markroxor
fuente
2

Cuando está en problemas, qué significa qué:

?%timeit o ??timeit

Para obtener los detalles:

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
fuente
1

Si desea imprimir el tiempo de ejecución de la celda de pared aquí es un truco, use

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

pero aquí asegúrate de que el %% del tiempo es una función mágica, así que ponlo en la primera línea de tu código .

si lo coloca después de alguna línea de su código, le dará un error de uso y no funcionará.

nemish zalavadiya neel
fuente