chore: refactor benchmarking to use benchmark.nvim
This commit is contained in:
parent
3fa3161aa9
commit
5fa528f552
4 changed files with 76 additions and 132 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -48,5 +48,6 @@ venv/
|
|||
doc/tags
|
||||
scripts/nvim_doc_tools
|
||||
scripts/nvim-typecheck-action
|
||||
tests/perf/
|
||||
scripts/benchmark.nvim
|
||||
perf/tmp/
|
||||
profile.json
|
||||
|
|
|
|||
20
Makefile
20
Makefile
|
|
@ -37,20 +37,19 @@ fastlint: scripts/nvim_doc_tools venv
|
|||
|
||||
## profile: use LuaJIT profiler to profile the plugin
|
||||
.PHONY: profile
|
||||
profile:
|
||||
nvim --clean -u tests/perf_harness.lua -c 'lua jit_profile()'
|
||||
profile: scripts/benchmark.nvim
|
||||
nvim --clean -u perf/bootstrap.lua -c 'lua jit_profile()'
|
||||
|
||||
## flame_profile: create a trace in the chrome profiler format
|
||||
.PHONY: flame_profile
|
||||
flame_profile:
|
||||
nvim --clean -u tests/perf_harness.lua -c 'lua flame_profile()'
|
||||
@echo "Visit https://ui.perfetto.dev/ and load the profile.json file"
|
||||
flame_profile: scripts/benchmark.nvim
|
||||
nvim --clean -u perf/bootstrap.lua -c 'lua flame_profile()'
|
||||
|
||||
## benchmark: benchmark performance opening directory with many files
|
||||
.PHONY: benchmark
|
||||
benchmark:
|
||||
nvim --clean -u tests/perf_harness.lua -c 'lua benchmark(10)'
|
||||
@cat tests/perf/benchmark.txt
|
||||
benchmark: scripts/benchmark.nvim
|
||||
nvim --clean -u perf/bootstrap.lua -c 'lua benchmark()'
|
||||
@cat perf/tmp/benchmark.txt
|
||||
|
||||
scripts/nvim_doc_tools:
|
||||
git clone https://github.com/stevearc/nvim_doc_tools scripts/nvim_doc_tools
|
||||
|
|
@ -58,7 +57,10 @@ scripts/nvim_doc_tools:
|
|||
scripts/nvim-typecheck-action:
|
||||
git clone https://github.com/stevearc/nvim-typecheck-action scripts/nvim-typecheck-action
|
||||
|
||||
scripts/benchmark.nvim:
|
||||
git clone https://github.com/stevearc/benchmark.nvim scripts/benchmark.nvim
|
||||
|
||||
## clean: reset the repository to a clean state
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf scripts/nvim_doc_tools scripts/nvim-typecheck-action venv .testenv tests/perf profile.json
|
||||
rm -rf scripts/nvim_doc_tools scripts/nvim-typecheck-action venv .testenv perf/tmp profile.json
|
||||
|
|
|
|||
63
perf/bootstrap.lua
Normal file
63
perf/bootstrap.lua
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
vim.opt.runtimepath:prepend("scripts/benchmark.nvim")
|
||||
vim.opt.runtimepath:prepend(".")
|
||||
|
||||
local bm = require("benchmark")
|
||||
bm.sandbox()
|
||||
|
||||
---@module 'oil'
|
||||
---@type oil.SetupOpts
|
||||
local setup_opts = {
|
||||
-- columns = { "icon", "permissions", "size", "mtime" },
|
||||
}
|
||||
|
||||
local DIR_SIZE = tonumber(vim.env.DIR_SIZE) or 100000
|
||||
local ITERATIONS = tonumber(vim.env.ITERATIONS) or 10
|
||||
local WARM_UP = tonumber(vim.env.WARM_UP) or 1
|
||||
local OUTLIERS = tonumber(vim.env.OUTLIERS) or math.floor(ITERATIONS / 10)
|
||||
local TEST_DIR = "perf/tmp/test_" .. DIR_SIZE
|
||||
|
||||
vim.fn.mkdir(TEST_DIR, "p")
|
||||
require("benchmark.files").create_files(TEST_DIR, "file %d.txt", DIR_SIZE)
|
||||
|
||||
function _G.jit_profile()
|
||||
require("oil").setup(setup_opts)
|
||||
local finish = bm.jit_profile({ filename = TEST_DIR .. "/profile.txt" })
|
||||
bm.wait_for_user_event("OilEnter", function()
|
||||
finish()
|
||||
end)
|
||||
require("oil").open(TEST_DIR)
|
||||
end
|
||||
|
||||
function _G.flame_profile()
|
||||
local start, stop = bm.flame_profile({
|
||||
pattern = "oil*",
|
||||
filename = "profile.json",
|
||||
})
|
||||
require("oil").setup(setup_opts)
|
||||
start()
|
||||
bm.wait_for_user_event("OilEnter", function()
|
||||
stop(function()
|
||||
vim.cmd.qall({ mods = { silent = true } })
|
||||
end)
|
||||
end)
|
||||
require("oil").open(TEST_DIR)
|
||||
end
|
||||
|
||||
function _G.benchmark()
|
||||
require("oil").setup(setup_opts)
|
||||
bm.run({ title = "oil.nvim", iterations = ITERATIONS, warm_up = WARM_UP }, function(callback)
|
||||
bm.wait_for_user_event("OilEnter", callback)
|
||||
require("oil").open(TEST_DIR)
|
||||
end, function(times)
|
||||
local avg = bm.avg(times, { trim_outliers = OUTLIERS })
|
||||
local std_dev = bm.std_dev(times, { trim_outliers = OUTLIERS })
|
||||
local lines = {
|
||||
table.concat(vim.tbl_map(bm.format_time, times), " "),
|
||||
string.format("Average: %s", bm.format_time(avg)),
|
||||
string.format("Std deviation: %s", bm.format_time(std_dev)),
|
||||
}
|
||||
|
||||
vim.fn.writefile(lines, "perf/tmp/benchmark.txt")
|
||||
vim.cmd.qall({ mods = { silent = true } })
|
||||
end)
|
||||
end
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
vim.fn.mkdir("tests/perf/.env", "p")
|
||||
local root = vim.fn.fnamemodify("./tests/perf/.env", ":p")
|
||||
|
||||
for _, name in ipairs({ "config", "data", "state", "runtime", "cache" }) do
|
||||
vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. name
|
||||
end
|
||||
|
||||
vim.opt.runtimepath:prepend(vim.fn.fnamemodify(".", ":p"))
|
||||
|
||||
---@module 'oil'
|
||||
---@type oil.SetupOpts
|
||||
local setup_opts = {
|
||||
-- columns = { "icon", "permissions", "size", "mtime" },
|
||||
}
|
||||
|
||||
local num_files = 100000
|
||||
|
||||
if not vim.uv.fs_stat(string.format("tests/perf/file %d.txt", num_files)) then
|
||||
vim.notify("Creating files")
|
||||
for i = 1, num_files, 1 do
|
||||
local filename = ("tests/perf/file %d.txt"):format(i)
|
||||
local fd = vim.uv.fs_open(filename, "a", 420)
|
||||
assert(fd)
|
||||
vim.uv.fs_close(fd)
|
||||
end
|
||||
end
|
||||
|
||||
local function wait_for_done(callback)
|
||||
vim.api.nvim_create_autocmd("User", {
|
||||
pattern = "OilEnter",
|
||||
once = true,
|
||||
callback = callback,
|
||||
})
|
||||
end
|
||||
|
||||
function _G.jit_profile()
|
||||
require("oil").setup(setup_opts)
|
||||
local outfile = "tests/perf/profile.txt"
|
||||
require("jit.p").start("3Fpli1s", outfile)
|
||||
local start = vim.uv.hrtime()
|
||||
require("oil").open("tests/perf")
|
||||
|
||||
wait_for_done(function()
|
||||
local delta = vim.uv.hrtime() - start
|
||||
require("jit.p").stop()
|
||||
print("Elapsed:", delta / 1e6, "ms")
|
||||
vim.cmd.edit({ args = { outfile } })
|
||||
end)
|
||||
end
|
||||
|
||||
function _G.benchmark(iterations)
|
||||
require("oil").setup(setup_opts)
|
||||
local num_outliers = math.floor(0.1 * iterations)
|
||||
local times = {}
|
||||
|
||||
local run_profile
|
||||
run_profile = function()
|
||||
-- Clear out state
|
||||
vim.cmd.enew()
|
||||
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
|
||||
if vim.api.nvim_buf_is_valid(bufnr) and bufnr ~= vim.api.nvim_get_current_buf() then
|
||||
vim.api.nvim_buf_delete(bufnr, { force = true })
|
||||
end
|
||||
end
|
||||
|
||||
local start = vim.uv.hrtime()
|
||||
wait_for_done(function()
|
||||
local delta = vim.uv.hrtime() - start
|
||||
table.insert(times, delta / 1e6)
|
||||
if #times < iterations then
|
||||
vim.schedule(run_profile)
|
||||
else
|
||||
-- Remove the outliers
|
||||
table.sort(times)
|
||||
for _ = 1, num_outliers do
|
||||
table.remove(times, 1)
|
||||
table.remove(times)
|
||||
end
|
||||
|
||||
local total = 0
|
||||
for _, time in ipairs(times) do
|
||||
total = total + time
|
||||
end
|
||||
|
||||
local lines = {
|
||||
table.concat(
|
||||
vim.tbl_map(function(t)
|
||||
return string.format("%dms", math.floor(t))
|
||||
end, times),
|
||||
" "
|
||||
),
|
||||
string.format("Average: %dms", math.floor(total / #times)),
|
||||
}
|
||||
vim.fn.writefile(lines, "tests/perf/benchmark.txt")
|
||||
vim.cmd.qall()
|
||||
end
|
||||
end)
|
||||
require("oil").open("tests/perf")
|
||||
end
|
||||
|
||||
run_profile()
|
||||
end
|
||||
|
||||
function _G.flame_profile()
|
||||
if not vim.uv.fs_stat("tests/perf/profile.nvim") then
|
||||
vim
|
||||
.system({ "git", "clone", "https://github.com/stevearc/profile.nvim", "tests/perf/profile.nvim" })
|
||||
:wait()
|
||||
end
|
||||
vim.opt.runtimepath:prepend(vim.fn.fnamemodify("./tests/perf/profile.nvim", ":p"))
|
||||
local profile = require("profile")
|
||||
profile.instrument_autocmds()
|
||||
profile.instrument("oil*")
|
||||
|
||||
require("oil").setup(setup_opts)
|
||||
profile.start()
|
||||
require("oil").open("tests/perf")
|
||||
wait_for_done(function()
|
||||
profile.stop("profile.json")
|
||||
vim.cmd.qall()
|
||||
end)
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue