自制轻量Profiler:精确定位哪个函数拖慢了服务端
-- Profiler.lua-- 函数级耗时统计,找出热点函数
local M = {}
local _stats = {}-- { funcName = { calls, totalMs, maxMs } }
local _enabled = false
function M.enable()_enabled = trueend
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
if not s then
_stats = { calls=0, totalMs=0, maxMs=0 }
s = _stats
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
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
感谢楼主分享! 快了快了,马上就能用VV了 3额外企鹅去翁 恶趣味饿
页:
[1]