From 8bb67d64e20d2e0d3e1892cb89d9bb8f558471e4 Mon Sep 17 00:00:00 2001 From: Mathias Fussenegger Date: Mon, 13 May 2024 17:26:57 +0200 Subject: perf(fs): normalize path only once in fs.dir Re-normalizing a path after a `joinpath` isn't necessary. Calling `normalize` on each child directory had quite a bit of impact when traversing a large directory. A simple test showed: Before: ~144ms After: ~80ms running the following logic against a dir with 4367 child folders and 25826 files: local files = {} local start = uv.hrtime() for name, type in vim.fs.dir(path, { depth = max_depth }) do table.insert(files, { name, type }) end local duration = uv.hrtime() - start Relates to https://github.com/neovim/neovim/issues/23291 --- runtime/lua/vim/fs.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'runtime/lua/vim') diff --git a/runtime/lua/vim/fs.lua b/runtime/lua/vim/fs.lua index 766dc09691..e70175bcbd 100644 --- a/runtime/lua/vim/fs.lua +++ b/runtime/lua/vim/fs.lua @@ -120,8 +120,9 @@ function M.dir(path, opts) skip = { opts.skip, { 'function' }, true }, }) + path = M.normalize(path) if not opts.depth or opts.depth == 1 then - local fs = vim.uv.fs_scandir(M.normalize(path)) + local fs = vim.uv.fs_scandir(path) return function() if not fs then return @@ -137,7 +138,7 @@ function M.dir(path, opts) --- @type string, integer local dir0, level = unpack(table.remove(dirs, 1)) local dir = level == 1 and dir0 or M.joinpath(path, dir0) - local fs = vim.uv.fs_scandir(M.normalize(dir)) + local fs = vim.uv.fs_scandir(dir) while fs do local name, t = vim.uv.fs_scandir_next(fs) if not name then -- cgit