查看: 51|回复: 3

[Lua] 自制轻量Profiler:精确定位哪个函数拖慢了服务端

[复制链接]

46

主题

42

回帖

1212

积分

金牌会员

积分
1212
发表于 2026-6-5 00:12:58 | 显示全部楼层 |阅读模式
-- Profiler.lua
-- 函数级耗时统计,找出热点函数

local M = {}
local _stats = {}  -- { funcName = { calls, totalMs, maxMs } }
local _enabled = false

function M.enable()  _enabled = true  end
function M.disable() _enabled = false end

-- 包装一个函数,自动计时
function M.wrap(name, fn)
    return function(...)
        if not _enabled then return fn(...) end

        local t0 = os.clock()
        local results = table.pack(fn(...))
        local elapsed = (os.clock() - t0) * 1000  -- 转ms

        local s = _stats[name]
        if not s then
            _stats[name] = { calls=0, totalMs=0, maxMs=0 }
            s = _stats[name]
        end
        s.calls   = s.calls + 1
        s.totalMs = s.totalMs + elapsed
        if elapsed > s.maxMs then s.maxMs = elapsed end

        return table.unpack(results, 1, results.n)
    end
end

-- 打印报告,按总耗时降序
function M.report(top)
    top = top or 10
    local list = {}
    for name, s in pairs(_stats) do
        table.insert(list, {
            name  = name,
            calls = s.calls,
            total = s.totalMs,
            avg   = s.totalMs / s.calls,
            max   = s.maxMs,
        })
    end
    table.sort(list, function(a, b) return a.total > b.total end)

    print(string.format("\n%-30s %6s %10s %8s %8s",
        "函数名", "调用数", "总耗时ms", "均值ms", "最大ms"))
    print(string.rep("-", 66))
    for i = 1, math.min(top, #list) do
        local r = list[i]
        print(string.format("%-30s %6d %10.2f %8.3f %8.3f",
            r.name, r.calls, r.total, r.avg, r.max))
    end
end

function M.reset() _stats = {} end
实战接入:

local Profiler = require("Profiler")
Profiler.enable()

-- 包装可疑的高频函数
GetPlayerRank    = Profiler.wrap("GetPlayerRank",    GetPlayerRank)
OnMonsterDie     = Profiler.wrap("OnMonsterDie",     OnMonsterDie)
DropSystem.roll  = Profiler.wrap("DropSystem.roll",  DropSystem.roll)
Identify.identify= Profiler.wrap("Identify.identify",Identify.identify)

-- 每小时打印一次 Top10 耗时函数
SetTimer(3600 * 1000, function()
    Profiler.report(10)
    Profiler.reset()
end)
return M

1

主题

34

回帖

6560

积分

论坛元老

积分
6560
发表于 2026-6-5 07:18:56 | 显示全部楼层
感谢楼主分享!

1

主题

228

回帖

1585

积分

金牌会员

积分
1585
发表于 2026-6-5 09:50:17 | 显示全部楼层
快了快了,马上就能用VV了

0

主题

18

回帖

217

积分

中级会员

积分
217
发表于 2026-6-5 10:01:42 | 显示全部楼层
3额外企鹅去翁 恶趣味饿
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表