Pular para o conteúdo

Como usar o cache do Python?

[

Caching em Python usando a Estratégia de Cache LRU

Existem muitas maneiras de obter aplicativos rápidos e responsivos. O caching é uma abordagem que, quando usada corretamente, torna as coisas muito mais rápidas, ao mesmo tempo em que diminui a carga nos recursos computacionais. O módulo functools do Python vem com o decorator @lru_cache, que permite que você faça cache do resultado de suas funções usando a estratégia Least Recently Used (LRU). Essa é uma técnica simples, porém poderosa, que você pode usar para aproveitar o poder do caching em seu código.

Neste tutorial, você aprenderá:

  • Quais estratégias de caching estão disponíveis e como implementá-las usando decoradores do Python
  • O que é a estratégia LRU e como ela funciona
  • Como melhorar o desempenho fazendo cache com o decorator @lru_cache
  • Como expandir a funcionalidade do decorator @lru_cache e fazer com que ele expire após um determinado tempo

Ao final deste tutorial, você terá um entendimento mais profundo de como o caching funciona e como aproveitá-lo em Python.

Caching e seus usos

O caching é uma técnica de otimização que você pode usar em seus aplicativos para manter dados recentes ou frequentemente utilizados em locais de memória que são mais rápidos ou mais baratos computacionalmente do que a fonte original.

Imagine que você está construindo um aplicativo leitor de notícias que busca as últimas notícias de diferentes fontes. Conforme o usuário navega pela lista, seu aplicativo faz o download dos artigos e os exibe na tela.

O que aconteceria se o usuário decidisse mover-se repetidamente para frente e para trás entre alguns artigos de notícias? A menos que você esteja fazendo cache dos dados, seu aplicativo teria que buscar o mesmo conteúdo todas as vezes! Isso deixaria o sistema do usuário lento e colocaria pressão extra no servidor que hospeda os artigos.

Uma abordagem melhor seria armazenar o conteúdo localmente após buscar cada artigo. Em seguida, quando o usuário decidisse abrir um artigo novamente, seu aplicativo poderia abrir o conteúdo a partir de uma cópia armazenada localmente, em vez de recorrer à fonte. Na ciência da computação, essa técnica é chamada de caching.

Implementando um cache usando um dicionário Python

Você pode implementar uma solução de caching em Python usando um dicionário.

Seguindo com o exemplo do leitor de notícias, em vez de ir diretamente para o servidor toda vez que você precisa fazer o download de um artigo, você pode verificar se possui o conteúdo em seu cache e ir para o servidor apenas se não tiver. Você pode usar o seguinte código como base:

cache = {}
def fetch_article(article_id):
if article_id in cache:
return cache[article_id]
else:
article_content = # fetch article content from server
cache[article_id] = article_content
return article_content

Neste código, a função fetch_article verifica se o ID do artigo está presente no cache (isto é, no dicionário cache). Se estiver, retorna o conteúdo do artigo diretamente do cache. Caso contrário, busca o conteúdo do artigo no servidor, armazena-o no cache e o retorna.

Com essa implementação básica de cache, você pode evitar buscar o mesmo conteúdo do servidor várias vezes, melhorando a velocidade e a eficiência da sua aplicação.

Estratégias de Caching

Existem várias estratégias de caching que você pode usar, dependendo das suas necessidades específicas. Além da estratégia LRU, existem outras, como FIFO (First-In, First-Out) e LFU (Least Frequently Used). Cada estratégia possui suas próprias vantagens e desvantagens.

A estratégia LRU (Least Recently Used) é uma abordagem comum em muitos sistemas de caching. Ela funciona mantendo um registro da ordem em que os itens são acessados e descartando o item menos recentemente usado quando o cache está cheio. Isso garante que os itens mais frequentemente acessados permaneçam no cache, enquanto os menos acessados são descartados para liberar espaço para novos itens.

Aprofundando na estratégia LRU Cache

Para entender melhor como a estratégia LRU funciona, vamos dar uma olhada em um exemplo simples.

Suponha que você tenha um cache com capacidade para até 3 itens. Você realiza as seguintes operações no cache:

  1. Adicionar o item A
  2. Adicionar o item B
  3. Adicionar o item C
  4. Acessar o item A
  5. Adicionar o item D

Com base nesses passos, a ordem de acesso aos itens é: A, B, C, A, D.

Quando o cache está cheio e um novo item (D) precisa ser adicionado, a estratégia LRU remove o item menos recentemente usado, que é o B. A nova ordem de acesso ao cache agora é: A, C, D.

Essa é a essência da estratégia LRU: remover o item menos recentemente usado quando o cache está cheio. Isso garante que os itens mais frequentemente acessados permaneçam no cache, enquanto os menos usados são descartados.

A biblioteca functools do Python oferece uma maneira conveniente de implementar a estratégia LRU usando o decorator @lru_cache. Vamos ver como usar isso em nosso código.

Usando @lru_cache para implementar um cache LRU em Python

Agora que entendemos o conceito e a estratégia LRU, vamos explorar como podemos implementar um cache LRU em Python usando o decorator @lru_cache.

O decorator @lru_cache é uma funcionalidade do módulo functools do Python e torna a implementação de um cache LRU muito mais fácil. Basta aplicar o decorator a uma função e começar a tirar proveito do caching.

Aqui está um exemplo de como usar o decorator @lru_cache:

from functools import lru_cache
@lru_cache(maxsize=3)
def fetch_article(article_id):
article_content = # fetch article content from server
return article_content

Nesse exemplo, a função fetch_article é decorada com o decorator @lru_cache, que recebe um argumento maxsize=3. Isso define o tamanho máximo do cache para 3 itens.

Agora, sempre que fetch_article é chamada com um determinado article_id, o decorator @lru_cache verifica se o resultado já está em cache. Se estiver, ele é retornado diretamente do cache. Caso contrário, a função é executada e o resultado é armazenado em cache para acessos futuros.

Essa abordagem permite que você obtenha o benefício do caching sem precisar lidar diretamente com o dicionário de cache e as operações de busca e adição de itens.

Adicionando Expiração ao Cache

Em alguns casos, você pode querer que o cache expire após um determinado tempo. Por exemplo, se você estiver fazendo cache de dados que são atualizados com frequência, pode ser necessário buscar novamente os dados após um determinado intervalo de tempo para garantir que você sempre esteja exibindo os dados mais recentes.

Felizmente, o decorator @lru_cache suporta a adição de expiração ao cache. Você pode fazer isso especificando o argumento ttl (time-to-live) na criação do cache.

Aqui está um exemplo de como adicionar expiração ao cache usando @lru_cache:

from functools import lru_cache
from datetime import timedelta
@lru_cache(maxsize=3, ttl=timedelta(minutes=30))
def fetch_article(article_id):
article_content = # fetch article content from server
return article_content

Neste exemplo, a função fetch_article é decorada com o decorator @lru_cache. Além do argumento maxsize, também estamos especificando o argumento ttl com o valor timedelta(minutes=30). Isso significa que o cache expirará após 30 minutos.

Quando o cache expira, a próxima chamada à função fetch_article com os mesmos argumentos resultará em uma busca atualizada dos dados no servidor. Isso garante que você esteja sempre mostrando os dados mais recentes, mesmo que eles tenham mudado desde a última vez que foram buscados.

Conclusão

O caching é uma técnica poderosa que pode melhorar significativamente o desempenho de suas aplicações. A biblioteca functools do Python oferece o decorator @lru_cache, que facilita a implementação do caching usando a estratégia LRU.

Neste tutorial, você aprendeu sobre o conceito de caching, diferentes estratégias de caching e como implementar um cache LRU usando o @lru_cache. Também exploramos como adicionar expiração ao cache para garantir que você sempre esteja exibindo os dados mais recentes.

Agora que você tem um entendimento mais profundo de como o caching funciona em Python, você pode começar a aplicar essa técnica em suas próprias aplicações para torná-las mais rápidas e eficientes.