Skip to content

url: speed up URLSearchParams - #65363

Open
anonrig wants to merge 2 commits into
nodejs:mainfrom
anonrig:cursor/url-searchparams-performance-603e
Open

url: speed up URLSearchParams#65363
anonrig wants to merge 2 commits into
nodejs:mainfrom
anonrig:cursor/url-searchparams-performance-603e

Conversation

@anonrig

@anonrig anonrig commented Aug 18, 2026

Copy link
Copy Markdown
Member

This speeds up WHATWG URLSearchParams without changing observable behavior.

Independent of the new URL() parse PR (#65361).

What changed

  • Parse: walk & / = with indexOf instead of a per-character state machine. When the input has no + or %, each component is a slice of the original string. Percent-decoding still runs only when a complete %HH sequence exists, so lone % and fake sequences like stay intact.
  • USVString: skip `${value}` when the value is already a string (constructor, append/get/set/has/delete).
  • Serialize: cache toString() until the list mutates; join encoded pairs instead of repeated +=.
  • Tests: test/parallel/test-whatwg-url-searchparams-fast-path.js covers leading ?, empty pairs, + / percent-decoding, invalid %, mutation cache invalidation, copy constructor isolation, record/sequence init, unpaired surrogates, and fake percent-encoding.

Tests

  • All test/parallel/test-whatwg-url-custom-searchparams*.js plus the new fast-path file
  • WPT test/wpt/test-url.js: 5107 passed, 0 unexpected failures

Local benches

Same binary family, both run with --no-node-snapshot (new JS is not in the V8 snapshot). Rates in ops/s:

Benchmark Before After
new URLSearchParams(string) noencode ~6.9M ~7.3M
new URLSearchParams(string) encodemany 6.9M 7.5M
new URLSearchParams(iterable) 9.9M 10.3M
toString() noencode (repeated) 7.7M ~213M
toString() encodemany (repeated) 4.9M ~200M
get() ~75M ~85M
has() ~52M ~59M

The large toString() jump is the serialization cache: the common “build params, stringify many times / read URL.href” path no longer re-encodes an unchanged list.

Ada already has a C url_search_params API. This keeps the implementation in JS to avoid a JS/C++ call on every get/append.

Assisted-by: Cursor

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/url

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. whatwg-url Issues and PRs related to the WHATWG URL implementation. labels Aug 18, 2026
@codecov

codecov Bot commented Aug 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.13%. Comparing base (f83e7df) to head (4ed2bdd).
⚠️ Report is 58 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #65363      +/-   ##
==========================================
- Coverage   90.31%   90.13%   -0.18%     
==========================================
  Files         751      752       +1     
  Lines      249956   251853    +1897     
  Branches    47204    47368     +164     
==========================================
+ Hits       225745   227005    +1260     
- Misses      15612    16180     +568     
- Partials     8599     8668      +69     
Files with missing lines Coverage Δ
lib/internal/url.js 93.24% <100.00%> (-0.04%) ⬇️

... and 96 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jasnell jasnell left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI agents are not permitted to use Signed-off-by

@cursor
cursor Bot force-pushed the cursor/url-searchparams-performance-603e branch from 1423a66 to e18874e Compare August 18, 2026 11:39
@anonrig

anonrig commented Aug 18, 2026

Copy link
Copy Markdown
Member Author

Removed the Signed-off-by trailer from the commit(s). An AI agent cannot attest the DCO.

@cursor
cursor Bot force-pushed the cursor/url-searchparams-performance-603e branch from e18874e to 9863db8 Compare August 18, 2026 12:49
anonrig and others added 2 commits August 18, 2026 12:49
Parse query strings with indexOf instead of a per-character state
machine, skip ToString when values are already strings, cache
toString() until the list mutates, and join serialized pairs.

Signed-off-by: Yagiz Nizipli <yagiz@nizipli.com>
Assisted-by: Cursor
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Leave lone '%' and non-hex percent sequences intact so serialization
matches the previous parser, and use native indexOf/slice/push on
the query-string hot path.

Signed-off-by: Yagiz Nizipli <yagiz@nizipli.com>
Assisted-by: Cursor
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
@cursor
cursor Bot force-pushed the cursor/url-searchparams-performance-603e branch 2 times, most recently from 4ed2bdd to 18331fb Compare August 18, 2026 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-ci PRs that need a full CI run. whatwg-url Issues and PRs related to the WHATWG URL implementation.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants