同参数重复调用是脚本热点的常见根源:装备战力合成、称号加成汇总,每个请求都从头算一遍。记忆化在函数外面包一层缓存:参数作键、结果作值,命中直接返回——用一次哈希查找换一次全量计算。Lua 的表本身就是哈希表,封装只需要几行,不改原函数一行代码。
通用记忆化包装器。示例代码如下:
local function memoize(fn)
local cache = {}
return function(x)
local hit = cache[x]
if hit ~= nil then
return hit
end
local r = fn(x)
cache[x] = r
return r
end
end
战力计算接线。示例代码如下:
local function calcPowerRaw(name)
local total = 0
for i = 1, 5000 do
total = total + math.sqrt(i) * (string.len(name) % 7 + 1)
end
return math.floor(total)
end
local calcPower = memoize(calcPowerRaw)
print(calcPower("裁决之杖"))
print(calcPower("裁决之杖"))
第二次调用直接命中缓存——5000 次开方只跑一遍,同参数的后续调用全部走缓存。
以 5000 次迭代的战力计算为例:未缓存时单次约 0.4 毫秒,千人在线每人每分钟查一次即每分钟约 400 毫秒 CPU;记忆化后命中路径约 0.001 毫秒,重复查询几乎零成本,每分钟 CPU 降到 1 毫秒量级。代价是缓存表随参数量增长:1000 个名字键约占 200KB 内存,换来的是计算量与键数解耦。
三个不适用场景:一是结果随时间变化的计算(排行榜名次每小时变),必须配过期淘汰,否则永远返回旧值;二是参数为表时不能直接作键(表按引用比较),要先拼成字符串键;三是参数空间巨大且命中率低时,缓存只涨内存不省时间——先统计重复率再决定是否记忆化。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
【语法】 一、抛坑提问:宠物跟随走直线太生硬,怎么走出圆滑弧线?二次贝塞尔曲线用两个端点加一个控制点,参数从 0 走到 1 …
【游戏】 一、一行代码拆解:SUB[missing] = actual —— 材料替换的全部骨架:替换表声明等价材料对,合成…
【游戏】 一、一行代码拆解:if WINNER == nil then WINNER = actor end —— 抢答判定…
【语法】 一、隐蔽陷阱:技能范围绕施法者旋转,逐点手算坐标容易把余弦与正弦位置写反——二维旋转公式为新横等于旧横乘余弦减旧纵…
【游戏】 一、一行代码拆解:BUYS = BUYS + 1 —— 次数增购的全部骨架:每日 3 次耗尽后可付费增购 1 次,…
【游戏】 一、一行代码拆解:LEND[id] = {who = actor, at = os.time()} —— 仓库借还…