Como medir o tempo gasto entre as linhas de código em python?

101

Então, em Java, podemos fazer Como medir o tempo gasto por uma função para executar

Mas como isso é feito em python? Para medir a hora de início e de término entre as linhas de códigos? Algo que faça isso:

import some_time_library

starttime = some_time_library.some_module()
code_tobe_measured() 
endtime = some_time_library.some_module()

time_taken = endtime - starttime
Alvas
fonte

Respostas:

159

Se você deseja medir o tempo de CPU, pode usar time.process_time()para Python 3.3 e superior:

import time
start = time.process_time()
# your code here    
print(time.process_time() - start)

A primeira chamada ativa o cronômetro e a segunda chamada informa quantos segundos se passaram.

Também existe uma função time.clock(), mas ela está obsoleta desde o Python 3.3 e será removida no Python 3.8.

Existem ferramentas de perfil melhores como timeite profile, no entanto, time.process_time () medirá o tempo de CPU e é sobre isso que você está perguntando.

Se você quiser medir o tempo do relógio de parede, use time.time().

Yevgen Yampolskiy
fonte
53
Não é assim que você usa time.clock()e time.clock()mede o tempo de CPU no Unix, mas o tempo de espera no Windows. É melhor usar time.time()onde o comportamento não varia com o sistema operacional. stackoverflow.com/questions/85451/…
Tim
4
Boa observação, @Tim. No entanto, outro post sobre a mesma questão cita python doc em time.clock () que "esta é a função a ser usada para benchmarking de Python ou algoritmos de temporização". Acho que vai à questão do que você realmente deseja medir.
Yevgen Yampolskiy
1
Uma coisa muito ruim sobre time.time () é que ele é afetado pela sincronização solar de tempo ntpdate etc. Eu diria que time.clock () seria a única alternativa confiável por causa disso
www.jensolsson.se
4
DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead
ismailarilik
2
Hmmm ... não tenho certeza do que estou fazendo de errado. Substituí # your code herecom time.sleep(10)e obtive 0,0 segundos. Adicionar for i in range(10000):/passproduziu os mesmos resultados. Em qualquer circunstância que tentei, time.process_time()sempre retorna o mesmo número. time.perf_counter()
Obtive os
58

Você também pode usar a timebiblioteca:

import time

start = time.time()

# your code

# end

print(f'Time: {time.time() - start}')
Akshaya Natarajan
fonte
1
@Hayat - Este método retorna a hora como um número de ponto flutuante expresso em segundos desde a época, em UTC. [ docs.python.org/3/library/time.html]
Anumoy Sutradhar
@AnumoySutradhar não realmente, já que está subtraindo uma época de uma época, você obtém a diferença de tempo entre os dois tempos.
Nasta de
28

Com a ajuda de uma pequena aula de conveniência, você pode medir o tempo gasto em linhas recuadas como esta:

with CodeTimer():
   line_to_measure()
   another_line()
   # etc...

Que mostrará o seguinte após a (s) linha (s) recuada (s) terminar a execução:

Code block took: x.xxx ms

ATUALIZAÇÃO: agora você pode começar a aula com pip install linetimere depois from linetimer import CodeTimer. Veja este projeto GitHub .

O código para a classe acima:

import timeit

class CodeTimer:
    def __init__(self, name=None):
        self.name = " '"  + name + "'" if name else ''

    def __enter__(self):
        self.start = timeit.default_timer()

    def __exit__(self, exc_type, exc_value, traceback):
        self.took = (timeit.default_timer() - self.start) * 1000.0
        print('Code block' + self.name + ' took: ' + str(self.took) + ' ms')

Você pode então nomear os blocos de código que deseja medir:

with CodeTimer('loop 1'):
   for i in range(100000):
      pass

with CodeTimer('loop 2'):
   for i in range(100000):
      pass

Code block 'loop 1' took: 4.991 ms
Code block 'loop 2' took: 3.666 ms

E aninhe- os:

with CodeTimer('Outer'):
   for i in range(100000):
      pass

   with CodeTimer('Inner'):
      for i in range(100000):
         pass

   for i in range(100000):
      pass

Code block 'Inner' took: 2.382 ms
Code block 'Outer' took: 10.466 ms

Quanto a timeit.default_timer(), ele usa o melhor cronômetro baseado na versão do SO e Python, veja esta resposta .

Assim como
fonte
11

Eu sempre prefiro verificar o tempo em horas, minutos e segundos (% H:% M:% S) formato:

from datetime import datetime
start = datetime.now()
# your code
end = datetime.now()
time_taken = end - start
print('Time: ',time_taken) 

resultado:

Time:  0:00:00.000019
Sayali Sonawane
fonte
3

Eu estava procurando uma maneira de gerar um tempo formatado com o mínimo de código, então aqui está minha solução. Muitas pessoas usam o Pandas de qualquer maneira, então, em alguns casos, isso pode economizar em importações adicionais de biblioteca.

import pandas as pd
start = pd.Timestamp.now()
# code
print(pd.Timestamp.now()-start)

Resultado:

0 days 00:05:32.541600

Eu recomendaria usar isso se a precisão do tempo não for o mais importante, caso contrário, use a timebiblioteca:

%timeit pd.Timestamp.now() saídas 3,29 µs ± 214 ns por loop

%timeit time.time() gera 154 ns ± 13,3 ns por loop

Marius
fonte
3

Colocar o código em uma função e, em seguida, usar um decorador para sincronizar é outra opção. ( Fonte ) A vantagem deste método é que você define o temporizador uma vez e o usa com uma linha adicional simples para cada função.

Primeiro, defina o timerdecorador:

import functools
import time

def timer(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.perf_counter()
        value = func(*args, **kwargs)
        end_time = time.perf_counter()
        run_time = end_time - start_time
        print("Finished {} in {} secs".format(repr(func.__name__), round(run_time, 3)))
        return value

    return wrapper

Em seguida, use o decorador ao definir a função:

@timer
def doubled_and_add(num):
    res = sum([i*2 for i in range(num)])
    print("Result : {}".format(res))

Vamos tentar:

doubled_and_add(100000)
doubled_and_add(1000000)

Resultado:

Result : 9999900000
Finished 'doubled_and_add' in 0.0119 secs
Result : 999999000000
Finished 'doubled_and_add' in 0.0897 secs

Observação: não sei por que usar em time.perf_countervez de time.time. Comentários são bem-vindos.

Alperen
fonte
1

Você também pode tentar isso:

from time import perf_counter

t0 = perf_counter()

...

t1 = perf_counter()
time_taken = t1 - t0
Manoj Kumar
fonte