Recordar resultados caros para no calcularlos dos veces
Memoización en diez líneas: una función que envuelve a otra y guarda lo que ya respondió.
The problem
Una función se llama cientos de veces con los mismos argumentos y cada llamada cuesta: una consulta, un cálculo pesado. Calcular una vez y recordar es la optimización más barata.
local function memoizar(fn)
local cache = {}
return function(n)
local v = cache[n]
if v == nil then
v = fn(n)
cache[n] = v
end
return v
end
end
local precio_con_impuesto
precio_con_impuesto = memoizar(function(codigo)
print(" (calculando " .. codigo .. ")") -- simula una consulta cara
local base = ({ A1 = 100, B2 = 250 })[codigo] or 0
return base * 1.07
end)
print(precio_con_impuesto("A1")) -- calcula
print(precio_con_impuesto("A1")) -- sale de la caché
print(precio_con_impuesto("B2")) -- calcula
Why it is written this way
- memoizar recibe una función y devuelve otra que hace lo mismo, pero consulta primero su tabla.
- La tabla cache vive en el cierre: cada función memoizada tiene la suya y nadie más la ve.
- En Lua las tablas son a la vez diccionario y arreglo, así que la caché no necesita ninguna estructura especial.
- El mensaje "calculando" aparece dos veces en tres llamadas: esa es la prueba de que funciona.
Guardalo como memo.lua y corré: lua memo.lua
La caché no vence nunca: si el precio cambia, la función sigue devolviendo el viejo. Y un resultado nil no se guarda, así que se recalcula cada vez.
Adapt it to your case with AI
The button copies this prompt with the code pasted below it. Replace the brackets with your own details and paste it into ChatGPT, Claude, Gemini or Copilot.
Tengo esta memoización en Lua. Extendela para funciones de varios argumentos, con vencimiento de [SEGUNDOS] segundos por entrada y un tope de [CANTIDAD] entradas descartando la más vieja. La voy a usar en [DÓNDE: un juego con LÖVE, Nginx con OpenResty, Redis, Neovim]. Agregá una función para vaciar la caché a mano y mostrame cómo medir cuántos aciertos tiene.
Example written and reviewed by hand.
Comments
No comments yet. Yours can be the first.
Did you adapt it to something of yours?
Tell me what you solved with it, or what it was missing.