mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
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
This commit is contained in:
parent
87a45ad9b9
commit
dcdefd0428
@ -488,6 +488,8 @@ end
|
|||||||
--- (default: `true`)
|
--- (default: `true`)
|
||||||
--- @field expand_env? boolean
|
--- @field expand_env? boolean
|
||||||
---
|
---
|
||||||
|
--- @field package _fast? boolean
|
||||||
|
---
|
||||||
--- Path is a Windows path.
|
--- Path is a Windows path.
|
||||||
--- (default: `true` in Windows, `false` otherwise)
|
--- (default: `true` in Windows, `false` otherwise)
|
||||||
--- @field win? boolean
|
--- @field win? boolean
|
||||||
@ -527,11 +529,13 @@ end
|
|||||||
function M.normalize(path, opts)
|
function M.normalize(path, opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
|
|
||||||
vim.validate({
|
if not opts._fast then
|
||||||
path = { path, { 'string' } },
|
vim.validate({
|
||||||
expand_env = { opts.expand_env, { 'boolean' }, true },
|
path = { path, { 'string' } },
|
||||||
win = { opts.win, { 'boolean' }, true },
|
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 win = opts.win == nil and iswin or not not opts.win
|
||||||
local os_sep_local = win and '\\' or '/'
|
local os_sep_local = win and '\\' or '/'
|
||||||
@ -555,11 +559,17 @@ function M.normalize(path, opts)
|
|||||||
path = path:gsub('%$([%w_]+)', vim.uv.os_getenv)
|
path = path:gsub('%$([%w_]+)', vim.uv.os_getenv)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Convert path separator to `/`
|
if win then
|
||||||
path = path:gsub(os_sep_local, '/')
|
-- 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
|
-- 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 = ''
|
local prefix = ''
|
||||||
|
|
||||||
if win then
|
if win then
|
||||||
@ -576,10 +586,15 @@ function M.normalize(path, opts)
|
|||||||
prefix = prefix:gsub('/+', '/')
|
prefix = prefix:gsub('/+', '/')
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Resolve `.` and `..` components and remove extraneous slashes from path, then recombine prefix
|
if not opts._fast then
|
||||||
-- and path. Preserve leading double slashes as they indicate UNC paths and DOS device paths in
|
-- 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.
|
-- 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 `.`
|
-- Change empty path to `.`
|
||||||
if path == '' then
|
if path == '' then
|
||||||
|
@ -85,7 +85,7 @@ function Loader.get_hash(path)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function normalize(path)
|
local function normalize(path)
|
||||||
return fs.normalize(path, { expand_env = false })
|
return fs.normalize(path, { expand_env = false, _fast = true })
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Gets the rtp excluding after directories.
|
--- Gets the rtp excluding after directories.
|
||||||
|
Loading…
Reference in New Issue
Block a user