Maneira simples de medir o tempo de execução da célula no notebook ipython

182

Gostaria de obter o tempo gasto na execução da célula, além da saída original da célula.

Para esse fim, tentei, %%timeit -r1 -n1mas ele não expõe a variável definida dentro da célula.

%%time funciona para a célula que contém apenas 1 instrução.

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 é a melhor maneira de fazer isso?

Atualizar

Estou usando o tempo de execução no Nbextension há algum tempo. Isso é ótimo.

colinfang
fonte
3
você realmente precisa cronometrar a exibição do valor? por que não colocar a xlinha de exibição na próxima célula?
21816 dbliss
Por que não aceitar uma resposta?
raratiru 28/03

Respostas:

46

Use a magia das células e este projeto no github de Phillip Cloud:

Carregue-o colocando-o na parte superior do seu notebook ou no arquivo de configuração, se você sempre quiser carregá-lo por padrão:

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

Se carregado, cada saída da execução subsequente da célula incluirá o tempo em minutos e segundos necessários para executá-la.

Philipp Schwarz
fonte
15
isso não funciona mais, pois% install_ext está obsoleto. Existe uma alternativa?
eyeApps LLC
13
Há uma solicitação de recebimento adressing esta questão ( github.com/cpcloud/ipython-autotime/pull/5 ), então você pode tentarpip install ipython-autotime
x0s
13
Agora %%timefunciona mesmo quando a última declaração não é print.
rhaps0dy
443

A única maneira que encontrei para superar esse problema é executando a última instrução com impressão.

Não se esqueça que a magia das células começa com %%e a magia das linhas começa com %.

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

Observe que quaisquer alterações realizadas dentro da célula não são levadas em consideração nas próximas células, algo que é contra-intuitivo quando existe um pipeline: um exemplo

Salvador Dalí
fonte
5
Agora %% time funciona mesmo quando a última instrução não é impressa, como @ rhaps0dy apontou acima.
Nealmcb 17/08/19
1
display (res) também funciona e é a solução preferida ao tentar exibir um dataframe do pandas ou outra coisa que exija uma saída estilizada.
dshefman
@dshefman Sim, isso está correto e facilita a portabilidade de notebooks de dados / spark também.
technazi
Não é um problema quando implementamos a primeira célula %%timee a=1a segunda célula não sabe o que aé?
Jason
3
PARA SUA INFORMAÇÃO. Descobri que variáveis ​​na célula testada agora são levadas em consideração nas próximas células. (20/02/2020) - Fei
Fei Yao
44

Uma maneira mais fácil é usar o plug-in ExecuteTime no pacote jupyter_contrib_nbextensions.

pip install jupyter_contrib_nbextensions
jupyter contrib nbextension install --user
jupyter nbextension enable execute_time/ExecuteTime
vForce
fonte
6
Esta é a resposta mais subestimada!
Daver
2
para alguém mergulhando no mar de respostas: esse é o único, basta instalá-lo e você verá o tempo de execução em cada célula em um bom formato
El pocho la pantera
14

Eu simplesmente adicionei %%timeno início da célula e consegui o tempo. Você pode usar o mesmo no cluster / ambiente virtual do Jupyter Spark usando o mesmo. Basta adicionar %%timena parte superior da célula e você obterá a saída. No cluster de spark usando o Jupyter, adicionei ao topo da célula e obtive a saída como abaixo: -

[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
fonte
Isso executa o código da célula com um número padrão? de vezes e depois leva a média? E a primeira declaração como o 'código de configuração'?
amsquareb 02/04
14
import time
start = time.time()
"the code you want to test stays here"
end = time.time()
print(end - start)
mina
fonte
1
Perfeito. É muito trabalhoso preservar o objeto de %% timeit e usá-lo na próxima célula
Paul
9

Isso não é exatamente bonito, mas sem software extra

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

Então você pode executá-lo como:

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

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

Às vezes, a formatação é diferente em uma célula ao usar print(res), mas o jupyter / ipython vem com a display. Veja um exemplo da diferença de formatação usando pandas abaixo.

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

A displayinstrução pode preservar a formatação. captura de tela

blehman
fonte
Isso executa o código da célula com um número padrão? de vezes e depois leva a média? E a primeira declaração como o 'código de configuração'?
amsquareb 02/04
2

convém também consultar o comando mágico de criação de perfil do python, %prunque fornece 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

então

%prun sum_of_lists(1000000)

retornará

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}

Acho útil quando se trabalha com grandes pedaços de código.

markroxor
fonte
2

Quando estiver com problemas, o que significa o que:

?%timeit ou ??timeit

Para obter os detalhes:

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

Se você quiser imprimir o tempo de execução das células da parede, aqui está um truque, use

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

mas aqui, verifique se %% time é uma função mágica. Coloque-o na primeira linha do seu código .

se você colocá-lo após alguma linha do seu código, isso causará um erro de uso e não funcionará.

nemish zalavadiya neel
fonte