0Pricing
Lua Academy · 课时

使用闭包实现记忆化

将开销较大的函数结果缓存到闭包持有的表中。

使用闭包实现记忆化 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。

什么是记忆化

记忆化会缓存开销较大的函数调用结果,使得使用相同参数的重复调用可以立即返回缓存结果。

基本记忆化包装器

闭包持有一个 cache 表。首次调用时计算并存储结果;再次调用时返回已存储的值。

local function memoize(fn)
  local cache = {}
  return function(x)
    if cache[x] == nil then
      cache[x] = fn(x)
    end
    return cache[x]
  end
end

记忆化斐波那契函数

对递归斐波那契函数进行记忆化,可以将其时间复杂度从指数级降为线性级。

local fib
fib = memoize(function(n)
  if n <= 1 then return n end
  return fib(n-1) + fib(n-2)
end)
print(fib(30))  -- 832040 (fast!)

多参数记忆化

对于包含多个参数的函数,请根据所有参数组合出缓存键字符串。

local function memoize2(fn)
  local cache = {}
  return function(a, b)
    local key = a .. "," .. b
    if cache[key] == nil then cache[key] = fn(a, b) end
    return cache[key]
  end
end

嵌套缓存表

对于混合类型的参数,请使用按各个参数作为键的嵌套表,从而无需字符串序列化即可实现 O(1) 查找。

local function nestedMemo(fn)
  local cache = {}
  return function(a, b)
    cache[a] = cache[a] or {}
    if cache[a][b] == nil then cache[a][b] = fn(a, b) end
    return cache[a][b]
  end
end

缓存失效

记忆化假定函数是纯函数(没有副作用,并且相同输入产生相同输出)。具有副作用的函数如果不谨慎处理缓存失效,不应进行记忆化。

基于 TTL 的记忆化

使用 os.time() 添加存活时间逻辑,使缓存条目过期。

local function memoizeTTL(fn, ttl)
  local cache = {}
  return function(x)
    local entry = cache[x]
    if entry and os.time() - entry.time < ttl then
      return entry.value
    end
    cache[x] = {value = fn(x), time = os.time()}
    return cache[x].value
  end
end

弱值缓存

使用弱值,这样在内存紧张时,缓存结果就可以被垃圾回收。

local function memoizeWeak(fn)
  local cache = setmetatable({}, {__mode = "v"})
  return function(x)
    if cache[x] == nil then cache[x] = fn(x) end
    return cache[x]
  end
end

递归记忆化模式

对于相互递归的函数,请在递归函数体使用记忆化包装器之前先为其赋值,这样递归调用就能命中缓存。

有界缓存(LRU 示意)

为了控制内存,请实现 LRU 缓存:当缓存超过最大大小时,淘汰最近最少使用的条目。

记忆化的实际应用

常见用途包括:开销较大的数学计算、数据库查询结果缓存、Lua 模式编译,以及配置文件解析。

记忆化问题

为什么记忆化只能应用于纯函数?

回顾:记忆化

记忆化使用闭包持有的缓存,根据参数键存储结果,从而消除重复计算。请使用弱表来保证内存安全,并为对时间敏感的缓存添加 TTL。

常见问题解答

「使用闭包实现记忆化」课时是免费的吗?

是的 — 「使用闭包实现记忆化」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。

「使用闭包实现记忆化」这节课中我会学到什么?

将开销较大的函数结果缓存到闭包持有的表中。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Lua Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「使用闭包实现记忆化」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Lua Academy 课中编写并运行代码吗?

能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 什么是上值?
  2. 闭包之间共享上值
  3. 工厂函数和生成器
  4. 使用闭包实现记忆化
← 返回 Lua Academy