Lua程序设计(七十五)

调优(Profile)

反射的另外一个常见的用法是用以调优,即程序使用资源的分析。对于事件相关的调优,最好使用 C 接口,因为每次调用钩子函数开销太大从而可能导致测试结果无效。

性能调优工具的主要数据结构是两个表,其中一个表将函数和它们的调用计数关联起来,另一个表关联函数和函数名。

local Counters = {}
local Names = {}

我们可以选择在性能分析完成后再获取函数的名称,但是如果能在一个函数 F 处于活动状态时获取其名称会得到更好的结果。

现在,我们定义一个钩子函数,该钩子的任务是获取当前正在被调用的函数,并递增相应的计数器,再收集函数名。

local function hook ()
	local f = debug.getinfo(2, "f").func
	local count = Counters[f]
	if count == nil then
		Counters[f] = 1
		Names[f] = debug.getinfo(2, "Sn")
	else
		Counters[f] = count + 1
	end
end

运行带有钩子的程序,假设我们要分析的程序位于一个文件中,且用户通过参数把该文件名传递给性能分析器。

% lua  profiler main-prog

这样,性能分析器就能从arg[1]中得到文件名,设置钩子并运行文件:

local f = assert(loadfile(arg[1]))
debug.sethook(hool, "c) --设置call时间的钩子
f()
debug.sethook()

我们通过函数 getname 来显式结果

function getname (func)
	local n = Names[func]
	if n.what == "C" then
		return n.name
	end
	local lc = string.format("[%s]:%d", n.short_src, n.linedefined)
	if n.what ~= "main" and n.namewhat ~= "" then
		return string.format("%s (%s)", lc, n.name)
	else
		return lc
	end
end

由于 Lua 语言中的函数名并不是特别确定,所以我们给每个函数再加上位置信息,以 file:line这样的形式给出。如果一个函数没有名称,那么就只使用它的位置。如果函数是 C 函数,那么就只使用它的名称。

for func, count in pairs(Counters) do
	print(getname(func), count)
end
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值