-
Notifications
You must be signed in to change notification settings - Fork 3
Lua Profiler
GMod's own vprof can tell you that gamemode hooks cost 8 ms, but not which hook, and profiling from Lua with debug.sethook breaks Starfall while detouring hook.Call costs more than it measures.
This does it from C++, above LuaJIT, so an armed profiler costs a couple of nanoseconds per call.
It is off by default.
Arm it with CRASHCAPTURE_PROFILE=1 at launch, or from Lua at any time:
crashcapture.set("profile", true)
timer.Simple(30, function()
for _, e in ipairs(crashcapture.profile(10)) do
print(("%-40s %8.2f ms self %6d calls"):format(e.name, e.self_ms, e.calls))
end
crashcapture.set("profile", false)
end)crashcapture.profile([limit]) returns a table sorted by self time, highest first, capped at limit entries (default 20, max 64):
| field | meaning |
|---|---|
name |
hook:Think, timer:MyAddon_Tick, timer.simple:x.lua:42, lua:sh_thing.lua:120, net:my_message, or <unattributed>
|
kind |
hook, timer, lua, net or other
|
source |
full path: timer creation site, or the Lua file for lua entries |
calls |
times entered during the window |
self_ms |
time in this entry, excluding nested Lua calls it made |
total_ms |
time including everything it called |
p50_ms |
median call |
p99_ms |
99th percentile call |
max_ms |
the single worst call |
The table itself also carries enabled, window_ms, completed, depth (Lua calls in flight right now), buckets / bucket_max, and dropped.
The profiler retires the current window and starts a fresh one every CRASHCAPTURE_PROFILE_WINDOW seconds (default 300), so it can be left armed indefinitely.
0 never rotates, use crashcapture.profile_reset() to zero the counters and start a fresh window yourself.
- Attribution is per hook name, not per addon.
-
hook:Thinkstill aggregates everyhook.Add("Think", ...)on the server. - It tells you which hook is expensive, not whose code.
-
-
timer.Simplecallbacks on Windows are named by the closure (lua:...) rather than astimer.simple:...- Because MSVC inlines the callback runner into the simple-timer drain and removes the hook point that supplies the timer's creation site.
Getting started
Usage
Features
For module developers