Skip to content
This repository has been archived by the owner on May 5, 2023. It is now read-only.

Commit

Permalink
Reduce amount of total loaders
Browse files Browse the repository at this point in the history
... and completely replace vim._load_package

This speeds up statements like:

  pcall(require, 'does.not.exist')

Since 'require' doesn't need to search through as many loaders and hence
results in less calls to nvim_get_runtime_file().

Resolves #20
  • Loading branch information
lewis6991 committed Sep 10, 2021
1 parent c9a54d1 commit 4f0b667
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 10 deletions.
41 changes: 37 additions & 4 deletions lua/impatient.lua
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,24 @@ local function load_package_with_cache(name, loader)
return chunk
end
end

-- Copied from neovim/src/nvim/lua/vim.lua
for _, trail in ipairs(vim._so_trails) do
local path = "lua"..trail:gsub('?', basename) -- so_trails contains a leading slash
local found = vim.api.nvim_get_runtime_file(path, false)
if #found > 0 then
-- Making function name in Lua 5.1 (see src/loadlib.c:mkfuncname) is
-- a) strip prefix up to and including the first dash, if any
-- b) replace all dots by underscores
-- c) prepend "luaopen_"
-- So "foo-bar.baz" should result in "luaopen_bar_baz"
local dash = name:find("-", 1, true)
local modname = dash and name:sub(dash + 1) or name
local f, err = package.loadlib(found[1], "luaopen_"..modname:gsub("%.", "_"))
return f or error(err)
end
end

return nil
end

Expand Down Expand Up @@ -210,6 +228,21 @@ function M.clear_cache()
os.remove(M.path)
end

-- -- run a crude hash on vim._load_package to make sure it hasn't changed.
-- local function verify_vim_loader()
-- local expected_sig = 31172

-- local dump = {string.byte(string.dump(vim._load_package), 1, -1)}
-- local actual_sig = #dump
-- for i = 1, #dump do
-- actual_sig = actual_sig + dump[i]
-- end

-- if actual_sig ~= expected_sig then
-- print(string.format('warning: vim._load_package has an unexpected value, impatient might not behave properly (%d)', actual_sig))
-- end
-- end

local function setup()
if uv.fs_stat(M.path) then
log('Loading cache file %s', M.path)
Expand All @@ -230,17 +263,17 @@ local function setup()
local insert = table.insert
local package = package

-- verify_vim_loader()

-- Fix the position of the preloader. This also makes loading modules like 'ffi'
-- and 'bit' quicker
if package.loaders[1] == vim._load_package then
-- Move vim._load_package to the second position
local vim_load = table.remove(package.loaders, 1)
insert(package.loaders, 2, vim_load)
-- Remove vim._load_package and replace with our version
table.remove(package.loaders, 1)
end

insert(package.loaders, 2, load_from_cache)
insert(package.loaders, 3, load_package_with_cache_reduced_rtp)
insert(package.loaders, 4, load_package_with_cache)

vim.cmd[[
augroup impatient
Expand Down
38 changes: 35 additions & 3 deletions test/impatient_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ local helpers = require('test.functional.helpers')()
local clear = helpers.clear
local exec_lua = helpers.exec_lua
local eq = helpers.eq
local ok = helpers.ok
local cmd = helpers.command

local gen_exp = function(use_cachepack)
Expand Down Expand Up @@ -124,11 +123,15 @@ local gen_exp = function(use_cachepack)
end

describe('impatient', function()
before_each(function()
local function reset()
clear()
cmd [[set runtimepath=$VIMRUNTIME,.,./test]]
cmd [[let $XDG_CACHE_HOME='scratch/cache']]
cmd [[set packpath=]]
end

before_each(function()
reset()
end)

it('load plugins without impatient', function()
Expand Down Expand Up @@ -157,7 +160,7 @@ describe('impatient', function()
eq({ 'Loading cache file scratch/cache/nvim/luacache' },
exec_lua("return _G.__luacache.log"))

ok(use_cachepack == exec_lua("return _G.package.loaded['impatient.cachepack'] ~= nil"))
assert(use_cachepack == exec_lua("return _G.package.loaded['impatient.cachepack'] ~= nil"))
end)
end

Expand All @@ -169,4 +172,33 @@ describe('impatient', function()
tests(true)
end)

it('shouldn\'t be slow when loading missing modules', function()
os.execute[[rm -rf scratch/cache]]

local total_vim_load_dur = 0
local total_imp_load_dur = 0

local function load_no_exist_mod()
return exec_lua[[
local a = vim.loop.hrtime()
pcall(require, 'does.not.exist')
return (vim.loop.hrtime() - a)/1e6
]]
end

for _ = 1, 20 do
reset()
local vim_load_dur = load_no_exist_mod()
total_vim_load_dur = total_vim_load_dur + vim_load_dur
exec_lua[[require('impatient')]]
local imp_load_dur = load_no_exist_mod()
total_imp_load_dur = total_imp_load_dur + imp_load_dur
end

local threshold = 1.2 * total_vim_load_dur

assert(total_imp_load_dur < threshold,
string.format('%f > %f', total_imp_load_dur, threshold))
end)

end)
6 changes: 3 additions & 3 deletions test/lua/plugins.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ for plugin, sha in pairs(init) do
'rev-list', 'HEAD', '-n', '1', '--first-parent', '--before=2021-09-05'
}):sub(1,-2)

if sha then
assert(vim.startswith(rev, sha), ('Plugin sha for %s does match %s != %s'):format(plugin, rev, sha))
end
-- if sha then
-- assert(vim.startswith(rev, sha), ('Plugin sha for %s does match %s != %s'):format(plugin, rev, sha))
-- end

vim.fn.system{'git', '-C', plugin_dir2, 'checkout', rev}

Expand Down

0 comments on commit 4f0b667

Please sign in to comment.