diff options
author | Lewis Russell <lewis6991@gmail.com> | 2024-05-14 17:29:28 +0100 |
---|---|---|
committer | Lewis Russell <me@lewisr.dev> | 2024-05-15 12:38:26 +0100 |
commit | dcdefd042840c7a6db5dce2963ac23c45a5287da (patch) | |
tree | 334b021fa547da0ace5c6bef188accf626966092 /runtime/lua/vim/fs.lua | |
parent | 87a45ad9b98e2e69c36091d397ad5b70a688b23f (diff) | |
download | rneovim-dcdefd042840c7a6db5dce2963ac23c45a5287da.tar.gz rneovim-dcdefd042840c7a6db5dce2963ac23c45a5287da.tar.bz2 rneovim-dcdefd042840c7a6db5dce2963ac23c45a5287da.zip |
perf(loader): use a quicker version of vim.fs.normalize
Problem:
vim.fs.normalize() normalizes too much vim.loader and is slow.
Solution:
Make it faster by doing less. This reduces the times spent in
vim.fs.normalize in vim.loader from ~13ms -> 1-2ms.
Numbers from a relative benchmark:
- Skipping `vim.validate()`: 285ms -> 230ms
- Skipping `path_resolve_dot()`: 285ms -> 60ms
- Skipping `double_slash`: 60ms -> 35ms
Diffstat (limited to 'runtime/lua/vim/fs.lua')
-rw-r--r-- | runtime/lua/vim/fs.lua | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/runtime/lua/vim/fs.lua b/runtime/lua/vim/fs.lua index e70175bcbd..58e79db0b4 100644 --- a/runtime/lua/vim/fs.lua +++ b/runtime/lua/vim/fs.lua @@ -488,6 +488,8 @@ end --- (default: `true`) --- @field expand_env? boolean --- +--- @field package _fast? boolean +--- --- Path is a Windows path. --- (default: `true` in Windows, `false` otherwise) --- @field win? boolean @@ -527,11 +529,13 @@ end function M.normalize(path, opts) opts = opts or {} - vim.validate({ - path = { path, { 'string' } }, - expand_env = { opts.expand_env, { 'boolean' }, true }, - win = { opts.win, { 'boolean' }, true }, - }) + if not opts._fast then + vim.validate({ + path = { path, { 'string' } }, + expand_env = { opts.expand_env, { 'boolean' }, true }, + win = { opts.win, { 'boolean' }, true }, + }) + end local win = opts.win == nil and iswin or not not opts.win local os_sep_local = win and '\\' or '/' @@ -555,11 +559,17 @@ function M.normalize(path, opts) path = path:gsub('%$([%w_]+)', vim.uv.os_getenv) end - -- Convert path separator to `/` - path = path:gsub(os_sep_local, '/') + if win then + -- Convert path separator to `/` + path = path:gsub(os_sep_local, '/') + end -- Check for double slashes at the start of the path because they have special meaning - local double_slash = vim.startswith(path, '//') and not vim.startswith(path, '///') + local double_slash = false + if not opts._fast then + double_slash = vim.startswith(path, '//') and not vim.startswith(path, '///') + end + local prefix = '' if win then @@ -576,10 +586,15 @@ function M.normalize(path, opts) prefix = prefix:gsub('/+', '/') end - -- Resolve `.` and `..` components and remove extraneous slashes from path, then recombine prefix - -- and path. Preserve leading double slashes as they indicate UNC paths and DOS device paths in + if not opts._fast then + -- Resolve `.` and `..` components and remove extraneous slashes from path, then recombine prefix + -- and path. + path = path_resolve_dot(path) + end + + -- Preserve leading double slashes as they indicate UNC paths and DOS device paths in -- Windows and have implementation-defined behavior in POSIX. - path = (double_slash and '/' or '') .. prefix .. path_resolve_dot(path) + path = (double_slash and '/' or '') .. prefix .. path -- Change empty path to `.` if path == '' then |