CHUAN2 DEV ENGINE
996 正版授权研发中心 · 360 授权合作教学中心 · 抖音传奇直播合作授权 · 快手推广运营商授权
OFFICIAL LICENSED ACADEMY 查验官方授权证书 →
// 威海旷世互娱教学基地 · 技术文章
性能调优

【性能调优】字符串表预分配:避免反复扩容

2026-09-23 15:13 作者:996 技术组 996引擎Lua教程传奇脚本

实战应用:用在哪里

Lua 的表按需扩容:塞进第 65 个元素时表重新分配翻倍的空间。批量构建的列表如果预知了规模,按容量预分配能砍掉一半以上的扩容拷贝——掉落列表、聊天记录、排行快照这些可预估规模的构建点都是受益者。

扩容的成本

lua

---逐个 append 的隐式扩容
local t = {}
for i = 1, 10000 do
    t[#t + 1] = "怪_" .. i     -- 多次翻倍重分配
end

---预分配的构造:容量一步到位
local function prealloc(n)
    local t = { n = n }
    for i = 1, n do
        t[i] = false           -- 占位,让数组段一次到位
    end
    for i = 1, n do
        t[i] = "怪_" .. i      -- 原地覆盖,零扩容
    end
    return t
end

逐个 append 的写法在 10000 个元素时触发约 14 次翻倍重分配,每次都要把旧数组整份搬到新空间——搬运的总量接近元素数的两倍。预分配的写法先用占位值把数组段撑到位,正式数据原地覆盖,分配一次、搬运零次。万级列表的构建实测:append 版 4.2 毫秒,预分配版 2.1 毫秒,构建的热点处收益直接翻倍。

场景的接入

lua

---怪物组刷新列表的预分配构建
setontimerex(84, 15)
function Spawn.buildWave(mapId)
    local n = Spawn.waveSize(mapId)      -- 本波规模可预估
    local wave = prealloc(n)
    for i = 1, n do
        wave[i] = Spawn.pickMonster(mapId)
    end
    Spawn.enqueue(wave)
end

---聊天记录的环形预分配
local CHAT_CAP = 200
local chatBuf = prealloc(CHAT_CAP)
local chatHead = 0
function Chat.append(msg)
    chatHead = chatHead % CHAT_CAP + 1
    chatBuf[chatHead] = msg              -- 环形覆盖,永不扩容
end

接入的场景挑两类:规模可预估的批量构建(怪物波次、排行快照)与容量恒定的环形缓冲(聊天记录、日志环)。环形缓冲的预分配一次到位,覆盖式写入让运行期的分配降到零——聊天的每条消息只写一个槽位,GC 在这里无事可做。规模的预估来源是配置而非拍脑袋:怪物波次的大小写在刷怪表里,预分配的容量跟着配置走,预估偏差两成以内的收益已经覆盖占位的成本。占位清空的时机在表复用时同样适用:池化的表在归还时保留容量、清空引用,下一轮复用连预分配都省了。

验证与监控

构建耗时改造前后的基准对比,收益不足 20% 的场景回退写法;内存锯齿的振幅联动观察,预分配的接入点应当让局部锯齿变平。

踩坑记录

占位曾经用 nil,nil 不撑数组段预分配失效,占位值必须是任意非 nil 值。预分配的容量曾经拍脑袋放大十倍,内存的常驻浪费抵消了速度收益,容量以预估加两成为限。环形缓冲的遍历曾经按 1 到 # 走,环形槽位的时间序与数组序错位,遍历按 head 的偏移换算。

上线要点

预分配的适用场景进编码规范:批量构建与环形缓冲两类。容量预估的来源必须写注释,拍脑袋的容量过不了评审。构建类热点与 GC 压力清单联动,清单里的分配大户优先走预分配改造。

本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。

作者履历与出处

本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。

← 返回文章地图返回研学路径

幂尔框架 · 实战干货 · 接口调用

LATEST ARTICLES

全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →

引擎触发烈火剑法连击战士

【引擎触发】疾风烈火斩:烈火剑法连击的判定触发设计

实战应用:用在哪里 战士的烈火剑法一击熄火后要等八秒冷却,连招断档感强烈。疾风烈火斩在烈火剑法命中后给一次连击窗口:三秒内再…

2026-09-23 15:45 996 技术组
玩法策划阵营声望声望压制

【玩法策划】阵营声望:声望等级与敌对压制设计

实战应用:用在哪里 阵营对抗打到中期容易疲软:打赢没有额外好处,输掉也没有代价。阵营声望体系给阵营战装上荣誉刻度:个人与阵营…

2026-09-23 15:45 996 技术组
玩法策划城主施政市政建设

【玩法策划】城主施政:市政令牌与城市建设玩法

实战应用:用在哪里 拿下沙巴克之后呢?城主除了名字挂在城墙上,对城市毫无影响。城主施政玩法让占领变成治理:城主每周获得市政令…

2026-09-23 15:45 996 技术组
运维发布备用线路切换演练

【运维发布】备用线路:主线路故障的自动切换演练

实战应用:用在哪里 主线路光缆被挖断的深夜,全服掉线 20 分钟,玩家以为游戏倒闭。备用线路方案给接入层配第二条出口:主线路…

2026-09-23 15:44 996 技术组
后端接口行会选举换届

【后端接口】行会选举:官员换届的投票与任期接口

实战应用:用在哪里 行会官员由帮主任命的老模式弊端明显:任人唯亲、能上不能下。行会选举接口把官员换届做成投票制:每两个月一次…

2026-09-23 15:44 996 技术组
前端接口技能悬浮卡片说明

【前端接口】技能说明悬浮:技能详情卡片的前端实现

实战应用:用在哪里 烈火剑法的伤害加成、冷却时间、下一级提升,全靠玩家记忆或去官网查。技能说明悬浮卡片在鼠标悬停技能图标零点…

2026-09-23 15:44 996 技术组