From ca37e8fe99cd384e06763228c8ee93d6ef624371 Mon Sep 17 00:00:00 2001 From: Yagiz Nizipli Date: Tue, 22 Sep 2026 06:32:31 +0000 Subject: [PATCH] url: skip resolve for already-absolute POSIX paths pathToFileURL always called path.resolve, even when the input was already an absolute POSIX path with no '.' / '..' or empty segments. Reuse that path and drop a trailing slash the same way posix.resolve does, so the later restore does not append a second slash when path.sep is '\' (Windows host, windows: false). Official benchmark/url/whatwg-url-to-and-from-path.js pathToFileURL is about 27% faster for /dev/null and about 45-48% faster when the path has a query or hash. fileURLToPath is unchanged. Assisted-by: a closed-source coding agent Signed-off-by: Yagiz Nizipli Co-authored-by: Yagiz Nizipli --- lib/internal/url.js | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/internal/url.js b/lib/internal/url.js index be6413eee86..a232c0f708b 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -1673,9 +1673,30 @@ function fileURLToPathBuffer(path, options = kEmptyObject) { function pathToFileURL(filepath, options = kEmptyObject) { const windows = options?.windows ?? isWindows; const isUNC = windows && StringPrototypeStartsWith(filepath, '\\\\'); - let resolved = isUNC ? - filepath : - (windows ? path.win32.resolve(filepath) : path.posix.resolve(filepath)); + let resolved; + if (isUNC) { + resolved = filepath; + } else if (!windows && + filepath.length > 0 && + StringPrototypeCharCodeAt(filepath, 0) === CHAR_FORWARD_SLASH && + StringPrototypeIndexOf(filepath, '.') === -1 && + StringPrototypeIndexOf(filepath, '//') === -1) { + // Already an absolute POSIX path with no '.' / '..' or empty segments. + // posix.resolve() drops a trailing slash except for '/'. Keep that + // so the restore below does not append a second slash when path.sep + // is '\\' (Windows host, windows: false). + let end = filepath.length; + while (end > 1 && + StringPrototypeCharCodeAt(filepath, end - 1) === + CHAR_FORWARD_SLASH) { + end--; + } + resolved = end === filepath.length ? + filepath : + StringPrototypeSlice(filepath, 0, end); + } else { + resolved = windows ? path.win32.resolve(filepath) : path.posix.resolve(filepath); + } if (isUNC || (windows && StringPrototypeStartsWith(resolved, '\\\\'))) { // UNC path format: \\server\share\resource // Handle extended UNC path and standard UNC path