1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
| -- sample_profiler.lua —— 采样式 Profiler
local SampleProfiler = {}
function SampleProfiler.new()
local self = {
samples = {}, -- 采样样本
sample_count = 0, -- 总采样次数
started = false,
interval = 10, -- 每 10 条指令采样一次
}
return setmetatable(self, {__index = SampleProfiler})
end
function SampleProfiler:start()
if self.started then return end
self.started = true
self.samples = {}
self.sample_count = 0
-- 采样回调
self.hook = function()
local info = debug.getinfo(2, "nS") -- 当前执行的函数
if info then
-- 记录函数名和所在行
local key = string.format("%s:%d",
info.source or "unknown",
info.currentline or 0)
self.samples[key] = (self.samples[key] or 0) + 1
self.sample_count = self.sample_count + 1
end
end
debug.sethook(self.hook, "", self.interval)
end
function SampleProfiler:stop()
if not self.started then return end
debug.sethook() -- 关闭 hook
self.started = false
end
function SampleProfiler:report(top_n)
if self.sample_count == 0 then
print("无采样数据")
return
end
top_n = top_n or 20 -- 默认显示 Top20
-- 排序
local sorted = {}
for key, count in pairs(self.samples) do
table.insert(sorted, {key = key, count = count})
end
table.sort(sorted, function(a, b) return a.count > b.count end)
print(string.format("\n===== Lua 采样 Profiling 报告 ====="))
print(string.format("总采样次数: %d", self.sample_count))
print(string.format("不同热点: %d 个", #sorted))
print(string.format("%-40s %10s %8s", "热点位置", "次数", "占比"))
print(string.rep("-", 62))
for i = 1, math.min(top_n, #sorted) do
local ratio = sorted[i].count / self.sample_count * 100
print(string.format("%-40s %10d %7.2f%%",
sorted[i].key, sorted[i].count, ratio))
end
end
return SampleProfiler
|