2023-01-02 10:28:18 +00:00
|
|
|
local ffi = require("ffi")
|
|
|
|
|
2022-12-27 12:34:07 +00:00
|
|
|
local M = {}
|
|
|
|
|
|
|
|
---@class LazyStats
|
|
|
|
M._stats = {
|
|
|
|
-- startuptime in milliseconds till UIEnter
|
|
|
|
startuptime = 0,
|
2024-06-03 08:18:43 +01:00
|
|
|
-- when true, startuptime is the accurate cputime for the Neovim process. (Linux & macOS)
|
2022-12-27 12:34:07 +00:00
|
|
|
-- this is more accurate than `nvim --startuptime`, and as such will be slightly higher
|
|
|
|
-- when false, startuptime is calculated based on a delta with a timestamp when lazy started.
|
2023-01-03 08:12:43 +00:00
|
|
|
real_cputime = false,
|
2022-12-27 12:34:07 +00:00
|
|
|
count = 0, -- total number of plugins
|
|
|
|
loaded = 0, -- number of loaded plugins
|
2023-01-02 10:28:18 +00:00
|
|
|
---@type table<string, number>
|
|
|
|
times = {},
|
2022-12-27 12:34:07 +00:00
|
|
|
}
|
|
|
|
|
2023-01-03 08:12:43 +00:00
|
|
|
---@type ffi.namespace*
|
2023-01-02 10:28:18 +00:00
|
|
|
M.C = nil
|
|
|
|
|
2022-12-27 12:34:07 +00:00
|
|
|
function M.on_ui_enter()
|
2023-01-02 10:28:18 +00:00
|
|
|
M._stats.startuptime = M.track("UIEnter")
|
2024-07-04 14:17:02 +01:00
|
|
|
require("lazy.core.util").track({ start = "startuptime" }, M._stats.startuptime * 1e6)
|
2023-01-13 08:00:15 +00:00
|
|
|
vim.api.nvim_exec_autocmds("User", { pattern = "LazyVimStarted", modeline = false })
|
2023-01-02 10:28:18 +00:00
|
|
|
end
|
2022-12-27 12:34:07 +00:00
|
|
|
|
2023-01-02 10:28:18 +00:00
|
|
|
function M.track(event)
|
|
|
|
local time = M.cputime()
|
|
|
|
M._stats.times[event] = time
|
|
|
|
return time
|
|
|
|
end
|
|
|
|
|
|
|
|
function M.cputime()
|
|
|
|
if M.C == nil then
|
2023-01-02 16:10:54 +00:00
|
|
|
pcall(function()
|
2024-11-20 21:09:54 +00:00
|
|
|
local pad = ""
|
|
|
|
-- If we're a 32-bit platform, we need to pad by 4 bytes.
|
|
|
|
if ffi.abi("32bit") then
|
|
|
|
pad = "int _tv_pad;"
|
|
|
|
end
|
|
|
|
|
|
|
|
local pad_before_nsec = ""
|
|
|
|
local pad_after_nsec = ""
|
|
|
|
-- Where we place the padding depends on the endianness.
|
|
|
|
if ffi.abi("le") then
|
|
|
|
pad_after_nsec = pad
|
|
|
|
else
|
|
|
|
pad_before_nsec = pad
|
|
|
|
end
|
|
|
|
|
2023-01-02 10:28:18 +00:00
|
|
|
ffi.cdef([[
|
2024-11-20 21:09:54 +00:00
|
|
|
typedef int64_t time_t;
|
2022-12-27 12:34:07 +00:00
|
|
|
typedef int clockid_t;
|
|
|
|
typedef struct timespec {
|
|
|
|
time_t tv_sec; /* seconds */
|
2024-11-20 21:09:54 +00:00
|
|
|
]] .. pad_before_nsec .. [[
|
2022-12-27 12:34:07 +00:00
|
|
|
long tv_nsec; /* nanoseconds */
|
2024-11-20 21:09:54 +00:00
|
|
|
]] .. pad_after_nsec .. [[
|
2022-12-27 12:34:07 +00:00
|
|
|
} nanotime;
|
|
|
|
int clock_gettime(clockid_t clk_id, struct timespec *tp);
|
|
|
|
]])
|
2023-01-03 08:12:43 +00:00
|
|
|
M.C = ffi.C
|
2023-01-02 10:28:18 +00:00
|
|
|
end)
|
|
|
|
end
|
2023-01-03 08:12:43 +00:00
|
|
|
|
|
|
|
local function real()
|
2022-12-27 12:34:07 +00:00
|
|
|
local pnano = assert(ffi.new("nanotime[?]", 1))
|
|
|
|
local CLOCK_PROCESS_CPUTIME_ID = jit.os == "OSX" and 12 or 2
|
|
|
|
ffi.C.clock_gettime(CLOCK_PROCESS_CPUTIME_ID, pnano)
|
2023-07-06 15:19:08 +01:00
|
|
|
return tonumber(pnano[0].tv_sec) * 1e3 + tonumber(pnano[0].tv_nsec) / 1e6
|
2023-01-03 08:12:43 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
local function fallback()
|
2024-03-22 07:58:36 +00:00
|
|
|
return (vim.uv.hrtime() - require("lazy")._start) / 1e6
|
2022-12-27 12:34:07 +00:00
|
|
|
end
|
2023-01-03 08:12:43 +00:00
|
|
|
|
|
|
|
local ok, ret = pcall(real)
|
|
|
|
if ok then
|
|
|
|
M.cputime = real
|
|
|
|
M._stats.real_cputime = true
|
|
|
|
return ret
|
|
|
|
else
|
|
|
|
M.cputime = fallback
|
|
|
|
return fallback()
|
|
|
|
end
|
2022-12-27 12:34:07 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function M.stats()
|
|
|
|
M._stats.count = 0
|
|
|
|
M._stats.loaded = 0
|
|
|
|
for _, plugin in pairs(require("lazy.core.config").plugins) do
|
|
|
|
M._stats.count = M._stats.count + 1
|
|
|
|
if plugin._.loaded then
|
|
|
|
M._stats.loaded = M._stats.loaded + 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return M._stats
|
|
|
|
end
|
|
|
|
|
|
|
|
return M
|