Skip to content

path: remove StringPrototypeCharCodeAt from more posix methods#63662

Open
whoekage wants to merge 1 commit into
nodejs:mainfrom
whoekage:perf/path-posix-indexing-extend
Open

path: remove StringPrototypeCharCodeAt from more posix methods#63662
whoekage wants to merge 1 commit into
nodejs:mainfrom
whoekage:perf/path-posix-indexing-extend

Conversation

@whoekage

Copy link
Copy Markdown

Summary

Extends the optimization landed in #54546 (posix.extname) to the remaining POSIX path methods still using StringPrototypeCharCodeAt. #54668 covers resolve/normalize/parse; this PR covers dirname, basename, and relative.

What changed

Replaced StringPrototypeCharCodeAt(path, i) === CHAR_FORWARD_SLASH with path[i] === '/' in three POSIX methods. Diff: +12 / −14 lines in lib/path.js.

Benchmark

Apple M1, 30 runs via benchmark/compare.js. Showing significant cases:

dirname-posix

path delta sig
/foo +12.45% ***
/foo/bar/baz/asdf/quux +8.82% ***
/foo/bar +8.82% ***
foo +6.34% *
foo/bar +2.26% *

basename-posix

pathext delta sig
/foo/bar/baz/asdf/quux.html|.html +8.38% ***
/foo/.bar.baz|.baz +8.25% ***
/foo/.bar.baz +6.90% ***
foo/bar. +5.94% ***
foo +5.78% *

relative-posix

paths delta sig
/var|/bin +3.28% **

Methodology validation

Control benchmark on extname-posix (unchanged in this PR) shows ±2% deltas without statistical significance, confirming methodology. No regressions on Win32 paths (slow path untouched).

Test plan

  • parallel/test-path* — all 17 pass
  • parallel/test-url-* — all 15 pass
  • parallel/test-fs-readfile/stat/realpath — pass
  • parallel/test-module-* — all 32 pass
  • Fuzz: 425 input cases identical to baseline
  • make lint-js — clean

Refs: #54546, #54668

Extends the optimization applied to posix.extname in nodejs#54546 to
posix.dirname, posix.basename, and posix.relative. nodejs#54668 covers
posix.resolve, posix.normalize, and posix.parse.

Replacing `StringPrototypeCharCodeAt(path, i) === CHAR_FORWARD_SLASH`
with `path[i] === '/'` is consistently faster on V8 because the
single-character string comparison hits a faster path than the
integer comparison after charCodeAt().

Benchmark (Apple M1, 30 runs via benchmark/compare.js):

  dirname-posix:
    path='/foo'                                  +12.45% ***
    path='/foo/bar/baz/asdf/quux'                 +8.82% ***
    path='/foo/bar'                               +8.82% ***
    path='foo'                                    +6.34% *
    path='foo/bar'                                +2.26% *

  basename-posix:
    pathext='/foo/bar/baz/asdf/quux.html|.html'   +8.38% ***
    pathext='/foo/.bar.baz|.baz'                  +8.25% ***
    pathext='/foo/.bar.baz'                       +6.90% ***
    pathext='foo/bar.'                            +5.94% ***
    pathext='foo'                                 +5.78% *

  relative-posix:
    paths='/var|/bin'                             +3.28% **

No regressions in Win32 paths (slow path untouched). Control
benchmark on extname (unchanged) shows ±2% noise without
significance, confirming methodology.
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/path

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. path Issues and PRs related to the path subsystem. labels May 30, 2026
@whoekage

whoekage commented Jun 5, 2026

Copy link
Copy Markdown
Author

Hi! Could a collaborator start CI here when convenient? The change is small
(+12/-14) and the path tests pass locally.

This extends the same StringPrototypeCharCodeAt(...) === CHAR_* to
path[i] === '*' conversion that was already accepted in #54546 (merged,
posix.extname) and is in progress in #54668, applied to the remaining posix
methods.

Related C++ path optimization: #63753.

Thanks!

@avivkeller avivkeller added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. request-ci Add this label to start a Jenkins CI on a PR. labels Jul 25, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Jul 25, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author ready PRs that have at least one approval, no pending requests for changes, and a CI started. needs-ci PRs that need a full CI run. path Issues and PRs related to the path subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants