O que é Memoização?
Memoização é sobre não repetir.
Pensa nesse cenário comigo:
Hoje em dia, quando você conhece alguém e quer manter contato, o que faz?
Pede o número (ou o Instagram) para a pessoa - e depois salva no seu celular. Certo?
Agora todas as vezes que você quiser falar com a pessoa, já tem as informações dela salvas no seu celular. Não precisa ir lá pessoalmente pedir os dados novamente.
Memoização é basicamente isso.
Deixamos o número da pessoa salvo (memoizamos) para não termos que ir lá pessoalmente pedir os dados novamente.
Você mantém informações salvas para não ter que refazer um processo.
Saindo desse ponto de vista mais metafórico - na prática - o que fazemos é salvar e reutilizar resultados de operações caras.
...Mas como assim?
Na teoria...
Imagine uma função que recebe um valor e retorna o produto dele por 1000000
:
function funcaoCara(x) {return x * 1000000;}funcaoCara(5); // => 5000000funcaoCara(5); // => 5000000
O problema?
Toda vez que a gente chamar essa função com o mesmo parâmetro irá recalcular - mesmo esse cálculo já tendo sido feito no passado.
Tipo ali - chamamos 2 vezes a função com o número 5, e nas duas vezes, ele irá refazer o cálculo.
Se quisermos otimizar isso - poderíamos memoizar - isto é, sempre que recebermos um parâmetro novo - fazemos o cálculo e salvamos o resultado para reutilizarmos depois:
const valoresJaCalculados = {};function funcaoCara(x) {if (x in valoresJaCalculados) {return valoresJaCalculados[x];}const result = x * 1000000;valoresJaCalculados[x] = result;return result;}console.log(funcaoCara(5)); // => 5000000console.log(funcaoCara(5)); // Memoizado => 5000000
O objeto valoresJaCalculados
- usando um sistema de key-value - irá manter os valores já calculados pela função cara.
A chave sendo o parâmetro, e o resultado sendo - isso mesmo - o resultado.
É um exemplo bem simples, e na vida real provavelmente não seria necessário otimizar.
... Mas e na vida real?
A memoização é bastante utilizada - principalmente por baixo dos panos em frameworks/linguagens em si.
É um hack de performance meio que universal.
Tipo o React - que disponibiliza o React.memo:
const ComponentMemoizado = React.memo(function Child({ nome }) {return <div>Olá, {nome}!</div>;});export default function App() {const [count, setCount] = React.useState(0);return (<div><button onClick={() => setCount(count + 1)}>Increment: {count}</button><ComponentMemoizado nome="John" /></div>);}
Nesse caso, ele só re-renderiza o ComponentMemoizado
caso o nome mude - independente se mudarmos o valor de count.
... No Python - memoizamos o resultado do fatorial de um valor n - limitando-se a manter em cache os últimos 1000 valores diferentes usados.
from functools import lru_cache@lru_cache(maxsize=1000)def fatorial(n):if n == 0:return 1return n * fatorial(n - 1)
Veja que a ideia é a mesma - o padrão se repete em todas as tecnologias.
Salvar um resultado para não refazer alguma operação - igual ao exemplo do contato no celular.
Além disso - é possível manualmente implementar sua própria memoização com Redis ou bibliotecas de cache em memória - aí vai do cenário e contexto.
O importante é entender o conceito para reutilizá-lo em outros lugares, independente da linguagem.
-Rapozo