一个Lua性能监控工具分享

首先是开启监控器方法,向Global注入RawsetGlobal方法

function Profiler:StartMonitor(type)
    self.MonitorType = type
    self.MemoryState = {}
    self.StartMemory = collectgarbage("count")
    self.CurrentMemory = self.StartMemory
    self.MonitorGlobal = {}
    setmetatable(_G, { __newindex = Profiler.RawsetGlobal })
    if type ~= self.MonitorType.Line or nil then
        self.MonitorStartTime = os.clock()
        self.FunctionTable = {}
        debug.sethook(Profiler.FunctionMonitor,type.Type,0)
    else
        debug.sethook(Profiler.LineMonitor,type.Type,0)
    end
end

function Profiler.RawsetGlobal(tb,k,v)
    local t = {}
    local info = debug.getinfo(2, "nlS")
    t.CurrentLine = info.currentline
    t.SrcFile = info.short_src
    t.FunctionName = info.name or 'Anonymous'
    t.Key = k
    t.Value = v
    Profiler.MonitorGlobal[k] = t
    rawset(tb, k, v)
end

 

function性能监控方法,写法如出一辙

function Profiler.FunctionMonitor(type)
    local funcinfo = debug.getinfo(2, 'ns')
    if type == "call" then
        Profiler:FunctionCall(funcinfo)
    elseif type == "return" then
        Profiler:FunctionReturn(funcinfo)
    end
end

function Profiler:FunctionCall(funcinfo)
    local functionTable = self:GetFunctionTable(funcinfo)
    assert(functionTable)
    if not functionTable.FunctionStartTime then
        functionTable.FunctionStartTime = os.clock()
    end
    functionTable.CallTime = os.clock()
    functionTable.CallCount = functionTable.CallCount + 1
end

function Profiler:FunctionReturn(funcinfo)
    local stopTime = os.clock()
    local report = self:FunctionReport(funcinfo)
    assert(report)
    report.StopTime = stopTime
    if report.CallTime and report.CallTime > 0 then
        report.TotalTime = report.TotalTime + (stopTime - report.CallTime)
    end
    report.localValueTable = report.localValueTable or {}
    local index = 1
    while true do
        local key, value = debug.getlocal(2, index)
        if not key then break end
        rawset(report.localValueTable,key, value)
        index = index + 1
    end
end

function Profiler:GetFunctionTable(funcinfo)
    local key = funcinfo.name or 'Unknow'
    local report = self.PerformanceReport[key] or {}
    if not report then
        report ={CallCount = 0,TotalTime = 0}
        self.FunctionTable[key] = report
    end
    return report
end

然后是结束监控返回self

function Profiler:StopMonitorFunction()
    self.StopTime = os.clock()
    self.SurplusMemory = self.CurrentMemory - self.StartMemory
    debug.sethook()
    local totalTime = self.StopTime - self.StartTime
    table.sort(self.FunctionTable, function(a, b)
        return a.Total_Time > b.Total_Time
    end)
    return self
end

附MonitorType

local m ={
    __add = function(a,b)
        local table = {}
        table.Type = a.Type..b.Type
        setmetatable(table,getmetatable(a))
        return table
    end,
    __eq = function(a,b)
        print(a.Type , b.Type)
        return a.Type == b.Type
    end
}
Profiler.MonitorTypeClass = {
    New = function(value)
        local table = {}
        table.Type = value
        setmetatable(table,m)
        return table
    end,
}

注:hook本身是会对原来的程序造成一定影响的,所以得出来的数据并非十分准确,最好是在另一个State开启注入

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值