Pular para o conteúdo

13 · Decoradores

Cache de Resultados

Memoização automática com @memoize e cache com expiração via @cached(ttl).

Nesta página

@memoize armazena o resultado de cada combinação de argumentos para sempre. É ideal para funções puras e caras cujos argumentos se repetem — como recursão exponencial ou lookups custosos:

Cache vitalício por argumentos; fibonacci(30) fica instantâneo.

01-memoize.zolo
Playground
// Feature: `@memoize` — automatic cache by arguments
// Syntax: `@memoize` before the `fn`. Cache lives for the lifetime of the program.
// When to use: pure, expensive functions (exponential recursion, parsing,
// lookups) where the same arguments repeat.

@memoize
fn fibonacci(n: int) -> int {
  if n <= 1 { return n }
  return fibonacci(n - 1) + fibonacci(n - 2)
}

// fib(30) would be slow without cache; with memoize it is instant.
print("fib(10) = {fibonacci(10)}")
// expected: fib(10) = 55
print("fib(20) = {fibonacci(20)}")
// expected: fib(20) = 6765
print("fib(30) = {fibonacci(30)}")

// expected: fib(30) = 832040

// Memoize also works with multiple arguments.
@memoize
fn pow(base: int, exp: int) -> int {
  if exp == 0 { return 1 }
  return base * pow(base, exp - 1)
}

print("2^10 = {pow(2, 10)}")
// expected: 2^10 = 1024
print("3^5 = {pow(3, 5)}")
// expected: 3^5 = 243

Quando os dados têm validade, use @cached(ttl) passando o tempo de vida em segundos. Após o TTL a função é re-executada; entre chamadas, o resultado guardado é devolvido sem custo:

Cache com expiração: TTL curto para cálculos, TTL longo para configurações.

02-cached-ttl.zolo
Playground
// Feature: `@cached(ttl)` — memoize with expiration
// Syntax: `@cached(<seconds>)`. After the TTL, the call is re-executed.
// When to use: data that is "fresh" within a window (price, quote,
// API response, remote configuration).

@cached(60)
fn expensive_calc(x: int) -> int {
  print("  computing cube({x})")
  return x * x * x
}

print("cube(5) = {expensive_calc(5)}")  // prints "computing"
print("cube(5) = {expensive_calc(5)}")  // cached, no "computing"
print("cube(7) = {expensive_calc(7)}")  // new argument -> re-executes
print("cube(7) = {expensive_calc(7)}")  // cached

// expected:
//   computing cube(5)
//   cube(5) = 125
//   cube(5) = 125
//   computing cube(7)
//   cube(7) = 343
//   cube(7) = 343

// Long TTL simulates "config loaded once".
@cached(3600)
fn load_config() -> str {
  print("  loading config")
  return "host=localhost;port=8080"
}

print(load_config())
print(load_config())
// expected:
//   loading config
//   host=localhost;port=8080
//   host=localhost;port=8080

Desafio

Troque o TTL de expensive_calc por 1 e chame-a duas vezes com o mesmo argumento em rápida sucessão. O que acontece? Adicione um @log para confirmar quantas vezes o corpo realmente executa.

Índice global

Encontre seu caminho pela Zolo

Experimente uma ideia

Comece por aqui

9 resultados

9 resultados

enespt-br