A lua profiler for neovim
WARNING: this is a gigantic hack that works by monkey patching all your lua functions. I made this for my own personal use to optimize my own plugins, and make no guarantees about stability, utility, or that it won't crash your neovim.
Here is a default config that you can copy/paste into the start of your init.lua:
local should_profile = os.getenv("NVIM_PROFILE")
if should_profile then
require("profile").instrument_autocmds()
if should_profile:lower():match("^start") then
require("profile").start("*")
else
require("profile").instrument("*")
end
end
local function toggle_profile()
local prof = require("profile")
if prof.is_recording() then
prof.stop()
vim.ui.input({ prompt = "Save profile to:", completion = "file", default = "profile.json" }, function(filename)
if filename then
prof.export(filename)
vim.notify(string.format("Wrote %s", filename))
end
end)
else
prof.start("*")
end
end
vim.keymap.set("", "<f1>", toggle_profile)
How do I use it?
When you want to run Neovim and profile something, start it with NVIM_PROFILE=1 nvim
. Then you can tap <F1>
to start a profile, and <F1>
again to complete the profile and save it to a file. If you instead want to profile the startup of neovim, do NVIM_PROFILE=start nvim
and then hit <F1>
as soon as neovim loads.
Warning: traces can be very large!
The trace files can grow extremely large very quickly, and they are stored in memory until exported. This means that it will balloon the memory usage of neovim, might take a long time to write out to disk, could possibly crash neovim, or might crash the trace viewer you use. To avoid this I'd recommend taking relatively short profiles, and wherever possible target the specific module(s) you care about. For example, instead of start("*")
, it would be much better if I could use start("aerial*")
to profile just my aerial.nvim plugin.
You can view the traces in chrome://tracing
or at https://ui.perfetto.dev/
For more details on the API, look at the docstrings in profile.lua