Move some of the iteration in to loa and access the values by the index
to reduce the number of loops we need todo to get items into teh results
buffer.
Currently the flow is:
1) Filter and sort the candidates in rust
2) Convert to a string and pass to lua
3) Split the string and add them as lines in a buffer in lua
Now the flow is:
1) Filter and sort the candidates in rust
2) Loop over an iterator in lua
3) Pass each item to lua as a pointer by the index
This removes quite a bit of the work that is needed to get the data into
lua as a table. We are first removing the loop that will join the
results vector into one string. Then we will remove the copy of this
string into lua. We will then finally remove the loop to split the
string and create a table from it in lua. All of this ends up in a 12%
speed up.
Output for `./scripts/bench 0.x`
Benchmark 1: HEAD
Time (mean ± σ): 2.667 s ± 0.065 s [User: 8.537 s, System: 1.420 s]
Range (min … max): 2.588 s … 2.767 s 10 runs
Benchmark 2: 0.x
Time (mean ± σ): 2.337 s ± 0.150 s [User: 9.564 s, System: 1.648 s]
Range (min … max): 2.161 s … 2.529 s 10 runs
Summary
HEAD ran
1.14 ± 0.08 times faster than 0.x
-------------------------------------
The percentage difference is -12.00%
-------------------------------------
71 lines
1.9 KiB
Lua
71 lines
1.9 KiB
Lua
local library_path = (function()
|
|
local root = string.sub(debug.getinfo(1).source, 2, #"/libivy.lua" * -1)
|
|
local release_path = root .. "../../target/release"
|
|
return package.searchpath("libivyrs", release_path .. "/?.so;" .. release_path .. "/?.dylib;")
|
|
end)()
|
|
|
|
local ffi = require "ffi"
|
|
local ok, ivy_c = pcall(ffi.load, library_path)
|
|
if not ok then
|
|
vim.api.nvim_err_writeln(
|
|
"libivyrs.so not found! Please ensure you have complied the shared library."
|
|
.. " For more info refer to the documentation, https://github.com/AdeAttwood/ivy.nvim#compiling"
|
|
)
|
|
|
|
return
|
|
end
|
|
|
|
ffi.cdef [[
|
|
void ivy_init(const char*);
|
|
char* ivy_cwd();
|
|
int ivy_match(const char*, const char*);
|
|
char* ivy_files(const char*, const char*);
|
|
|
|
int ivy_files_iter(const char*, const char*);
|
|
int ivy_files_iter_len(int);
|
|
char* ivy_files_iter_at(int, int);
|
|
void ivy_files_iter_delete(int);
|
|
]]
|
|
|
|
local iter_mt = {
|
|
__len = function(self)
|
|
return self.length
|
|
end,
|
|
__index = function(self, index)
|
|
-- Pass in our index -1. This will map lua's one based indexing to zero
|
|
-- based indexing that we are using in the rust lib.
|
|
local item = ffi.string(ivy_c.ivy_files_iter_at(self.id, index - 1))
|
|
return { content = item }
|
|
end,
|
|
__newindex = function(_, _, _)
|
|
error("attempt to update a read-only table", 2)
|
|
end,
|
|
__gc = function(self)
|
|
ivy_c.ivy_files_iter_delete(self.id)
|
|
end,
|
|
}
|
|
|
|
local libivy = {}
|
|
|
|
libivy.ivy_init = function(dir)
|
|
ivy_c.ivy_init(dir)
|
|
end
|
|
|
|
libivy.ivy_cwd = function()
|
|
return ffi.string(ivy_c.ivy_cwd())
|
|
end
|
|
|
|
libivy.ivy_match = function(pattern, text)
|
|
return ivy_c.ivy_match(pattern, text)
|
|
end
|
|
|
|
libivy.ivy_files = function(pattern, base_dir)
|
|
local iter_id = ivy_c.ivy_files_iter(pattern, base_dir)
|
|
local iter_len = ivy_c.ivy_files_iter_len(iter_id)
|
|
local iter = { id = iter_id, length = iter_len }
|
|
setmetatable(iter, iter_mt)
|
|
|
|
return iter
|
|
end
|
|
|
|
return libivy
|