lua脚本的api调用性能进行分析

最近把xmake的luaprofile从它那里抽出来单独使用,以防有时需要对lua api进行性能分析

module("profiler",package.seeall)

function profiler:start(mode)
	if mode and mode == "trace" then
		debug.sethook(profiler._traceing_handler,'cr',0)
	else
		self._REPORTS = {}
		self._REPORTS_BY_TITLE = {}
		self._STARTIME = os.clock()

		debug.sethook(profiler._profiling_handler,'cr',0)
	end
end

function profiler:stop(mode)
	if mode and mode == "trace" then
		debug.sethook()
	else
		self._STOPTIME = os.clock()
		debug.sethook()

		local totaltime = self._STOPTIME - self._STARTIME

		table.sort(self._REPORTS,function(a,b)
			return a.totaltime > b.totaltime
		end)

		for _,report in ipairs(self._REPORTS) do
			local percent = (report.totaltime/ totaltime) * 100
			if percent < 1 then
				break
			end
		
			print(string.format("%.3f, %.2f%%, %d, %s", report.totaltime, percent, report.callcount, report.title))

		end
	end
end

function profiler._profiling_handler(hooktype)
	local funcinfo = debug.getinfo(2,"nS")

	if hooktype == "call" then
		profiler:_profiling_call(funcinfo)
	elseif hooktype == "return" then
		profiler:_profiling_return(funcinfo)
	end
end

function profiler._traceing_handler(hooktype)
	local funcinfo = debug.getinfo(2,'nS')
	if hooktype == "call" then
		local name = funcinfo.name
		local source = funcinfo.short_src or 'C_FUNC'
		if name and os.isfile(source) then
			local line = string.format("%d",funcinfo.linedefined or 0)
			--source = path.relative(source,_PROGRAM_DIR)
			--utils.print("%-30s: %s: %s", name, source, line)
			print(string.format("%s: %s: %s", name, source, line))
		end
	end
end

function profiler:_profiling_call(funcinfo)
	local stoptime = os.clock()

	local report = self:_func_report(funcinfo)
	assert(report)

	report.calltime = os.clock()

	report.callcount = report.callcount + 1
end

function profiler:_profiling_return(funcinfo)
	local stoptime = os.clock()
	local report = self:_func_report(funcinfo)
	assert(report)

	if report.calltime and report.calltime > 0 then
		report.totaltime = report.totaltime + (stoptime - report.calltime)
		report.calltime = 0
	end
end

function profiler:_func_title(funcinfo)
	assert(funcinfo)
	local name = funcinfo.name or "anonymous"
	local line = string.format("%d",funcinfo.linedefined or 0)
	local source = funcinfo.short_src or "C_FUNC"
	-- if os.isfile(source) then
	-- 	source = path.relative(source,_PROGRAM_DIR)
	-- end	
	return string.format("%s: %s: %s", name, source, line)
end

function profiler:_func_report(funcinfo)
	local functitle = self:_func_title(funcinfo)
	local report = self._REPORTS_BY_TITLE[functitle]

	if not report then
		report = {
			title = functitle,
			callcount = 0,
			totaltime = 0,
		}
		self._REPORTS_BY_TITLE[functitle] = report
		table.insert(self._REPORTS,report)
	end
	return report
end

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值