Some checks failed
Detach Plugins / check (FlyGrep.vim) (push) Has been cancelled
Detach Plugins / check (GitHub.vim) (push) Has been cancelled
Detach Plugins / check (JavaUnit.vim) (push) Has been cancelled
Detach Plugins / check (SourceCounter.vim) (push) Has been cancelled
Detach Plugins / check (cpicker.nvim) (push) Has been cancelled
Detach Plugins / check (dein-ui.vim) (push) Has been cancelled
Detach Plugins / check (git.vim) (push) Has been cancelled
Detach Plugins / check (iedit.vim) (push) Has been cancelled
Detach Plugins / check (scrollbar.vim) (push) Has been cancelled
Detach Plugins / check (vim-chat) (push) Has been cancelled
Detach Plugins / check (vim-cheat) (push) Has been cancelled
Detach Plugins / check (vim-todo) (push) Has been cancelled
Detach Plugins / check (xmake.vim) (push) Has been cancelled
test / Linux (nvim, nightly) (push) Has been cancelled
test / Linux (nvim, v0.3.8) (push) Has been cancelled
test / Linux (nvim, v0.4.0) (push) Has been cancelled
test / Linux (nvim, v0.4.2) (push) Has been cancelled
test / Linux (nvim, v0.4.3) (push) Has been cancelled
test / Linux (nvim, v0.4.4) (push) Has been cancelled
test / Linux (nvim, v0.5.0) (push) Has been cancelled
test / Linux (nvim, v0.5.1) (push) Has been cancelled
test / Linux (nvim, v0.6.0) (push) Has been cancelled
test / Linux (nvim, v0.6.1) (push) Has been cancelled
test / Linux (nvim, v0.7.0) (push) Has been cancelled
test / Linux (nvim, v0.7.2) (push) Has been cancelled
test / Linux (nvim, v0.8.0) (push) Has been cancelled
test / Linux (nvim, v0.8.1) (push) Has been cancelled
test / Linux (nvim, v0.8.2) (push) Has been cancelled
test / Linux (nvim, v0.8.3) (push) Has been cancelled
test / Linux (nvim, v0.9.0) (push) Has been cancelled
test / Linux (nvim, v0.9.1) (push) Has been cancelled
test / Linux (true, vim, v7.4.052) (push) Has been cancelled
test / Linux (true, vim, v7.4.1689) (push) Has been cancelled
test / Linux (true, vim, v7.4.629) (push) Has been cancelled
test / Linux (true, vim, v8.0.0027) (push) Has been cancelled
test / Linux (true, vim, v8.0.0183) (push) Has been cancelled
test / Linux (vim, nightly) (push) Has been cancelled
test / Linux (vim, v8.0.0184) (push) Has been cancelled
test / Linux (vim, v8.0.1453) (push) Has been cancelled
test / Linux (vim, v8.1.2269) (push) Has been cancelled
test / Linux (vim, v8.2.2434) (push) Has been cancelled
test / Linux (vim, v8.2.3995) (push) Has been cancelled
test / Windows (nvim, nightly) (push) Has been cancelled
test / Windows (nvim, v0.3.8) (push) Has been cancelled
test / Windows (nvim, v0.4.2) (push) Has been cancelled
test / Windows (nvim, v0.4.3) (push) Has been cancelled
test / Windows (nvim, v0.4.4) (push) Has been cancelled
test / Windows (nvim, v0.5.0) (push) Has been cancelled
test / Windows (nvim, v0.5.1) (push) Has been cancelled
test / Windows (nvim, v0.6.0) (push) Has been cancelled
test / Windows (nvim, v0.6.1) (push) Has been cancelled
test / Windows (nvim, v0.7.0) (push) Has been cancelled
test / Windows (nvim, v0.7.2) (push) Has been cancelled
test / Windows (nvim, v0.8.0) (push) Has been cancelled
test / Windows (nvim, v0.8.1) (push) Has been cancelled
test / Windows (nvim, v0.8.2) (push) Has been cancelled
test / Windows (nvim, v0.8.3) (push) Has been cancelled
test / Windows (nvim, v0.9.0) (push) Has been cancelled
test / Windows (nvim, v0.9.1) (push) Has been cancelled
test / Windows (vim, nightly) (push) Has been cancelled
test / Windows (vim, v7.4.1185) (push) Has been cancelled
test / Windows (vim, v7.4.1689) (push) Has been cancelled
test / Windows (vim, v8.0.0027) (push) Has been cancelled
test / Windows (vim, v8.0.1453) (push) Has been cancelled
test / Windows (vim, v8.1.2269) (push) Has been cancelled
test / Windows (vim, v8.2.2434) (push) Has been cancelled
test / Windows (vim, v8.2.3995) (push) Has been cancelled
docker / docker (push) Has been cancelled
mirror / check (coding) (push) Has been cancelled
mirror / check (gitee) (push) Has been cancelled
mirror / check (gitlab) (push) Has been cancelled
127 lines
3.5 KiB
Lua
127 lines
3.5 KiB
Lua
local B = {}
|
||
local stat = require "plenary.benchmark.stat"
|
||
|
||
local get_stats = function(results)
|
||
local ret = {}
|
||
|
||
ret.max, ret.min = stat.maxmin(results)
|
||
ret.mean = stat.mean(results)
|
||
ret.median = stat.median(results)
|
||
ret.std = stat.std_dev(results)
|
||
|
||
return ret
|
||
end
|
||
|
||
local get_output = function(index, res, runs)
|
||
-- divine with a sutable one / 1e3, 1e6, 1e9
|
||
local time_types = { "ns", "μs", "ms" }
|
||
|
||
local get_leading = function(time)
|
||
time = math.floor(time)
|
||
local count = 0
|
||
repeat
|
||
time = math.floor(time / 10)
|
||
count = count + 1
|
||
until time <= 0
|
||
return count
|
||
end
|
||
|
||
local get_best_fmt = function(time)
|
||
for _, v in ipairs(time_types) do
|
||
if math.abs(time) < 1000.0 then
|
||
return string.format("%s%3.1f %s", string.rep(" ", 3 - get_leading(time)), time, v)
|
||
end
|
||
time = time / 1000.0
|
||
end
|
||
return string.format("%.1f %s", time, "s")
|
||
end
|
||
|
||
return string.format(
|
||
"Benchmark #%d: '%s'\n Time(mean ± σ): %s ± %s\n Range(min … max): %s … %s %d runs\n",
|
||
index,
|
||
res.name,
|
||
get_best_fmt(res.stats.mean),
|
||
get_best_fmt(res.stats.std),
|
||
get_best_fmt(res.stats.min),
|
||
get_best_fmt(res.stats.max),
|
||
runs
|
||
)
|
||
end
|
||
|
||
local get_summary = function(res)
|
||
if #res == 1 then
|
||
return ""
|
||
end
|
||
|
||
local fastest_mean = math.huge
|
||
local fastest_index = 1
|
||
for i, benchmark in ipairs(res) do
|
||
if benchmark.stats.mean < fastest_mean then
|
||
fastest_mean = benchmark.stats.mean
|
||
fastest_index = i
|
||
end
|
||
end
|
||
|
||
if fastest_mean == math.huge then
|
||
return ""
|
||
end
|
||
|
||
local output = {}
|
||
local fastest = res[fastest_index].stats
|
||
for i, benchmark in ipairs(res) do
|
||
if i ~= fastest_index then
|
||
local result = benchmark.stats
|
||
local ratio = result.mean / fastest.mean
|
||
|
||
-- // https://en.wikipedia.org/wiki/Propagation_of_uncertainty#Example_formulas
|
||
-- // Covariance asssumed to be 0, i.e. variables are assumed to be independent
|
||
local ratio_std = ratio
|
||
* math.sqrt(math.pow(result.std / result.mean, 2) + math.pow(fastest.std / fastest.mean, 2))
|
||
|
||
table.insert(output, string.format(" %.1f ± %.1f times faster than '%s'\n", ratio, ratio_std, benchmark.name))
|
||
end
|
||
end
|
||
|
||
return string.format("Summary\n '%s' ran\n%s", res[fastest_index].name, table.concat(output, ""))
|
||
end
|
||
|
||
---@class benchmark_run_opts
|
||
---@field warmup number @number of initial runs before starting to track time.
|
||
---@field runs number @number of runs to make
|
||
---@field fun table<array<string, function>> @functions to execute
|
||
|
||
---Benchmark a function
|
||
---@param name string @benchmark name
|
||
---@param opts benchmark_run_opts
|
||
local bench = function(name, opts)
|
||
vim.validate {
|
||
opts = { opts, "table" },
|
||
fun = { opts.fun, "table" },
|
||
}
|
||
opts.warmup = vim.F.if_nil(opts.warmup, 3)
|
||
opts.runs = vim.F.if_nil(opts.runs, 5)
|
||
|
||
opts.fun = type(opts.fun) == "function" and { opts.fun } or opts.fun
|
||
local output = { string.format("Benchmark Group: '%s' -----------------------\n", name) }
|
||
local res = {}
|
||
for i, fun in ipairs(opts.fun) do
|
||
res[i] = { name = fun[1], results = {} }
|
||
for _ = 1, opts.warmup do
|
||
fun[2]()
|
||
end
|
||
for j = 1, opts.runs do
|
||
local start = vim.loop.hrtime()
|
||
fun[2]()
|
||
res[i].results[j] = vim.loop.hrtime() - start
|
||
end
|
||
res[i].stats = get_stats(res[i].results)
|
||
table.insert(output, get_output(i, res[i], opts.runs))
|
||
end
|
||
|
||
print(string.format("%s\n%s", table.concat(output, ""), get_summary(res)))
|
||
|
||
return res
|
||
end
|
||
|
||
return bench
|