Pular para o conteúdo

Como Usar o Timer em Python?

[

Funções de Timer em Python: Três Maneiras de Monitorar Seu Código

por Geir Arne Hjelle (intermediário)

Enquanto muitos desenvolvedores reconhecem o Python como uma linguagem de programação eficaz, programas em Python puro podem ser executados mais lentamente do que seus equivalentes em linguagens compiladas como C, Rust e Java. Neste tutorial, você aprenderá a usar um timer Python para monitorar a velocidade de execução dos seus programas.

Neste tutorial, você aprenderá a utilizar:

  • time.perf_counter() para medir o tempo em Python
  • Classes para manter o estado
  • Gerenciadores de contexto para trabalhar com um bloco de código
  • Decoradores para personalizar uma função

Você também obterá conhecimento sobre como as classes, gerenciadores de contexto e decoradores funcionam. Enquanto explora exemplos de cada conceito, você será inspirado a usar um ou vários deles no seu código, para calcular o tempo de execução do código, bem como em outras aplicações. Cada método tem suas vantagens, e você aprenderá qual utilizar dependendo da situação. Além disso, você terá um timer Python funcional que poderá usar para monitorar seus programas!

Temporizadores Python

Primeiramente, você dará uma olhada em um código de exemplo que será utilizado ao longo do tutorial. Mais tarde, você adicionará um timer Python a esse código para monitorar seu desempenho. Você também aprenderá algumas das maneiras mais simples de medir o tempo de execução desse exemplo.

Funções de Timer Python

Se você verificar o módulo time embutido no Python, notará várias funções que podem medir o tempo:

  • monotonic()
  • perf_counter()
  • process_time()
  • time()

O Python 3.7 introduziu várias novas funções, como thread_time(), bem como versões em nanossegundos de todas as funções acima, com um sufixo _ns. Por exemplo, perf_counter_ns() é a versão em nanossegundos do perf_counter(). Essas funções são usadas para medir o tempo em diferentes contextos, dependendo do seu próprio caso de uso.

Exemplo: Baixando Tutoriais

Vamos dar uma olhada em um exemplo prático para entender como usar o perf_counter() para medir o tempo de execução de uma tarefa. Suponha que você queira baixar 3 tutoriais diferentes da Internet. Você pode usar o perf_counter() para medir o tempo que leva para realizar essa tarefa:

import requests
import time
def download_tutorial(url):
response = requests.get(url)
if response.status_code == 200:
print(f"Downloaded tutorial from {url}")
else:
print(f"Failed to download tutorial from {url}")
def download_all_tutorials():
urls = [
"https://www.example.com/tutorial1",
"https://www.example.com/tutorial2",
"https://www.example.com/tutorial3"
]
start_time = time.perf_counter()
for url in urls:
download_tutorial(url)
end_time = time.perf_counter()
execution_time = end_time - start_time
print(f"Downloaded all tutorials in {execution_time:.2f} seconds")
download_all_tutorials()

Nesse exemplo, a função download_tutorial() realiza o download de um tutorial a partir de uma URL fornecida usando a biblioteca requests. A função download_all_tutorials() executa essa função para cada URL na lista urls e mede o tempo total de execução usando o perf_counter(). O tempo de execução é então impresso na saída.

Seu Primeiro Temporizador em Python

Agora que você viu um exemplo de como usar o perf_counter() para medir o tempo de execução, vamos criar uma função simples chamada timer() que irá facilitar o uso desse contador de tempo:

import time
def timer():
return time.perf_counter()
start_time = timer()
# Código que deseja medir o tempo de execução
end_time = timer()
execution_time = end_time - start_time
print(f"Execution time: {execution_time:.2f} seconds")

Nesse exemplo, você define uma função timer() que simplesmente retorna o valor do perf_counter(), permitindo que você o chame para definir o início e o fim do código que deseja medir. Você pode então calcular o tempo de execução e imprimi-lo na saída.

Uma Classe de Timer em Python

Agora que você já conhece as funções de timer em Python, vamos explorar outra abordagem: criar uma classe de timer personalizada. Isso permitirá maior flexibilidade e reutilização do seu timer em diferentes partes do código.

Entendendo Classes em Python

Antes de criar a classe de timer, vamos recapitular alguns conceitos básicos de classes em Python. Uma classe é uma estrutura que encapsula dados e métodos relacionados. Ela é utilizada para criar objetos, que são instâncias da classe. Os objetos podem acessar os métodos e as variáveis de instância definidos na classe.

Criando uma Classe de Timer em Python

Vamos criar uma classe chamada Timer que facilitará a criação e o uso de timers em Python.

import time
class Timer:
def __enter__(self):
self.start_time = time.perf_counter()
return self
def __exit__(self, exc_type, exc_value, exc_traceback):
self.end_time = time.perf_counter()
self.execution_time = self.end_time - self.start_time
print(f"Execution time: {self.execution_time:.2f} seconds")
with Timer():
# Código que deseja medir o tempo de execução

Nesse exemplo, definimos uma classe Timer que implementa dois métodos especiais: __enter__() e __exit__(). O método __enter__() é executado quando entramos em um bloco with Timer(): e define o tempo inicial usando o perf_counter(). Ele também retorna a própria instância da classe para que possamos acessar outros métodos e variáveis de instância.

O método __exit__() é executado quando saímos do bloco with e define o tempo final usando o perf_counter(). A diferença entre os tempos inicial e final é calculada e armazenada na variável execution_time. Por fim, imprimimos o tempo de execução na saída.

Com essa classe, podemos agora usar a sintaxe do bloco with para medir o tempo de execução de qualquer código que desejamos.

Um Gerenciador de Contexto de Timer em Python

Outra abordagem interessante é a criação de um gerenciador de contexto para o timer em Python. Isso nos permitirá medir o tempo de execução de um bloco de código sem a necessidade de repetir o código do timer em cada iteração.

Entendendo Gerenciadores de Contexto em Python

Um gerenciador de contexto em Python é um objeto que define os métodos __enter__() e __exit__(), permitindo que ele seja utilizado em um bloco with. Quando entramos no bloco with, o método __enter__() é executado, e quando saímos do bloco with, o método __exit__() é executado.

Criando um Gerenciador de Contexto de Timer em Python

Vamos criar um gerenciador de contexto chamado TimerContext que facilitará a medição do tempo de execução de um bloco de código.

import time
from contextlib import contextmanager
@contextmanager
def TimerContext():
start_time = time.perf_counter()
yield
end_time = time.perf_counter()
execution_time = end_time - start_time
print(f"Execution time: {execution_time:.2f} seconds")
with TimerContext():
# Código que deseja medir o tempo de execução

Nesse exemplo, usamos o módulo contextlib e decoramos a função TimerContext() com o decorador @contextmanager. Isso nos permite tratar essa função como um gerenciador de contexto.

Dentro da função TimerContext(), definimos o tempo inicial usando o perf_counter() e usamos a keyword yield para indicar o início do bloco de código que desejamos medir. Quando saímos desse bloco, o código abaixo do yield é executado, definindo o tempo final, calculando a diferença entre os tempos e imprimindo o tempo de execução na saída.

Essa abordagem nos permite medir o tempo de execução de qualquer bloco de código sem precisar repetir o código do timer em cada iteração.

Um Decorador de Timer em Python

A última abordagem que vamos explorar é a criação de um decorador de timer em Python. Um decorador é um padrão de projeto que permite adicionar comportamento a uma função existente. Nesse caso, usaremos um decorador para medir o tempo de execução de uma função específica.

Entendendo Decoradores em Python

Em Python, um decorador é uma função que aceita outra função como argumento e retorna uma nova função. A nova função pode adicionar funcionalidade ao código original, antes ou depois da execução da função original.

Criando um Decorador de Timer em Python

Vamos criar um decorador chamado timer_decorator que nos permitirá medir o tempo de execução de qualquer função.

import time
from functools import wraps
def timer_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
start_time = time.perf_counter()
result = func(*args, **kwargs)
end_time = time.perf_counter()
execution_time = end_time - start_time
print(f"Execution time: {execution_time:.2f} seconds")
return result
return wrapper
@timer_decorator
def my_function():
# Código da função que desejamos medir o tempo de execução
my_function()

Nesse exemplo, definimos uma função chamada timer_decorator() que aceita uma função func como argumento. Dentro dessa função, definimos uma função interna wrapper() que é retornada como resultado do decorador.

A função wrapper() é decorada com o decorador @wraps(func), que copia as informações relevantes da função original func para a função interna wrapper(). Isso é importante para que a função interna mantenha o mesmo nome, documentação e assinatura da função original.

Dentro da função wrapper(), definimos o tempo inicial usando o perf_counter(), chamamos a função original func(*args, **kwargs), definimos o tempo final, calculamos a diferença entre os tempos e imprimimos o tempo de execução na saída.

Agora, podemos simplesmente decorar qualquer função com o decorador @timer_decorator para medir o tempo de execução dessa função.

Outras Funções de Temporizador em Python

Além das funções de timer mencionadas anteriormente, existem outras maneiras de medir o tempo de execução de um código em Python.

Usando Funções de Temporizador Alternativas em Python

Para medir o tempo de execução de um código, você também pode considerar o uso das seguintes funções:

  • time.process_time() para medir o tempo de CPU gasto pelo seu código
  • time.time() para obter o tempo atual em segundos desde a época (1 de janeiro de 1970)
  • time.thread_time() para medir o tempo de CPU gasto em um segmento específico

Essas funções podem ser usadas dependendo do contexto específico em que você deseja medir o tempo de execução do seu código.

Estimando o Tempo de Execução com timeit

Outra ferramenta útil para medir o tempo de execução de um código é o módulo timeit. Ele fornece uma interface fácil de usar para medir o tempo de execução de pequenas porções de código várias vezes e calcular a média.

Aqui está um exemplo de como usar o timeit para medir o tempo de execução de uma função:

import timeit
def my_function():
# Código da função que desejamos medir o tempo de execução
execution_time = timeit.timeit(my_function, number=1000)
print(f"Average execution time: {execution_time:.2f} seconds")

Nesse exemplo, usamos a função timeit.timeit() para medir o tempo de execução da função my_function() executada 1000 vezes. O resultado é a média do tempo de execução dessas 1000 iterações.

Encontrando Gargalos no Seu Código com Profilers

Se você precisa identificar os pontos em seu código onde a execução está mais lenta, você pode usar um profiler. Os profilers são ferramentas que ajudam a encontrar gargalos no desempenho do seu código, mostrando quais partes estão consumindo mais recursos computacionais ou levando mais tempo para serem executadas.

Existem várias ferramentas de profiling disponíveis em Python, como o cProfile, line_profiler e memory_profiler. Essas ferramentas podem ser utilizadas para analisar a velocidade de execução do código e identificar partes que podem ser otimizadas.

Conclusão

Neste tutorial, você aprendeu várias maneiras de usar um timer Python para monitorar o desempenho do seu código. Você explorou o uso de funções de timer embutidas, uma classe de timer personalizada, um gerenciador de contexto de timer e um decorador de timer.

Cada uma dessas abordagens tem suas vantagens, e você pode escolher a que melhor se adapta às suas necessidades. Você agora tem um timer Python funcional que pode usar para monitorar seus programas e identificar partes que podem ser otimizadas.

Esperamos que este tutorial tenha sido útil para você e que você possa aplicar esses conhecimentos no seu próprio código Python.

Recursos

Aqui estão alguns recursos adicionais que podem ajudá-lo a aprofundar seus conhecimentos sobre temporizadores em Python:

Dê uma olhada nesses recursos para aprender mais sobre o assunto e aprimorar suas habilidades em temporização de código Python!