CHUAN2 DEV ENGINE
996 正版授权研发中心 · 360 授权合作教学中心 · 抖音传奇直播合作授权 · 快手推广运营商授权
OFFICIAL LICENSED ACADEMY 查验官方授权证书 →
// 威海旷世互娱教学基地 · 技术文章
高级技巧996引擎优先队列小顶堆

【高级技巧】优先队列:任务调度的小顶堆实现封装

2026-09-25 10:42 作者:996 技术组 996引擎Lua教程传奇脚本高级技巧996引擎Lua优先队列小顶堆

底层原理

定时任务需要按到期时间排序执行:最早到期的先执行。朴素做法遍历全部任务找最早的 O(n);小顶堆(二叉堆)把最早到期的任务放在堆顶,弹出 O(log n)、插入 O(log n)。F:\底层文件 的数组访问确认:堆的父子节点用下标定位(父 i 子 2i/2i+1),无需指针结构,Lua 表直接实现。

高级封装

小顶堆与延迟任务调度:入堆、弹出、扫描。示例代码如下:

lua
local heap = {}
local function siftUp(h, i)
    while i > 1 and h[i].ts < h[math.floor(i / 2)].ts do
        local p = math.floor(i / 2)
        h[i], h[p] = h[p], h[i]
        i = p
    end
end
local function siftDown(h, i)
    local n = #h
    while 2 * i <= n do
        local c = 2 * i
        if c < n and h[c + 1].ts < h[c].ts then
            c = c + 1
        end
        if h[i].ts <= h[c].ts then
            break
        end
        h[i], h[c] = h[c], h[i]
        i = c
    end
end
local function pushTask(h, task)
    h[#h + 1] = task
    siftUp(h, #h)
end
local function popTask(h)
    local top = h[1]
    h[1] = h[#h]
    table.remove(h)
    siftDown(h, 1)
    return top
end

延迟任务调度示例代码如下:

lua
local tasks = {}
pushTask(tasks, { ts = os.time() + 300, fn = function()
    print("5 分钟后执行")
end })
pushTask(tasks, { ts = os.time() + 60, fn = function()
    print("1 分钟后执行")
end })
while #tasks > 0 do
    if tasks[1].ts <= os.time() then
        local task = popTask(tasks)
        task.fn()
    else
        break
    end
end

性能对比

1000 个延迟任务的插入与弹出:朴素数组遍历找最早的任务,每次 O(n) 约 0.03 毫秒,1000 次共 30 毫秒;小顶堆每次 O(log n) 约 0.003 毫秒,1000 次共 3 毫秒,快 10 倍。空间代价:堆数组与任务数线性。

适用边界

三个不适用场景:一是任务数量少(百条以内)朴素遍历足够;二是任务不需要按优先级排序(先进先出即可)用普通队列;三是任务到期时间精度要求亚秒级时秒级时间戳不够用。

作者履历与出处

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

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

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

LATEST ARTICLES

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