perf: SIMD percent-decode and form-urlencoded encode/decode - #1231
perf: SIMD percent-decode and form-urlencoded encode/decode#1231anonrig wants to merge 2 commits into
Conversation
Percent-encode tails and dense %XX decode were still scalar after the absolute-URL fast path grew nibble-table SIMD. Scan 16-byte windows with SSSE3/NEON (pshufb/tbl classifiers, five %XX groups per load) while keeping percent_encode_index inlined so short setters stay cheap. Search-params to_string now encodes directly with '+' for space. Closes #1120. Co-authored-by: Yagiz Nizipli <anonrig@users.noreply.github.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1231 +/- ##
==========================================
+ Coverage 63.00% 63.57% +0.56%
==========================================
Files 38 38
Lines 7628 7741 +113
Branches 3496 3516 +20
==========================================
+ Hits 4806 4921 +115
- Misses 749 750 +1
+ Partials 2073 2070 -3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
CodSpeed on #1218/#1230 showed 16-byte encode classify regresses SetHash and the official percent_encode examples. Gate the nibble-table walk on a 48-byte remainder and keep it noinline so setter-sized percent_encode stays a tight scalar tail. Co-authored-by: Yagiz Nizipli <anonrig@users.noreply.github.com>
Merging this PR will degrade performance by 5.48%
Warning Please fix the performance issues or acknowledge them on CodSpeed. Performance Changes
Tip Investigate this regression by commenting Comparing Footnotes
|
Percent-encode/decode and
application/x-www-form-urlencodedwere still scalar after the absolute-URL fast path grew nibble-table SIMD (#1216). Issue #1120 called this out. Prior attempts missed:percent_encode_indexor 16-byte encode classify regresses short setters on CodSpeedThis keeps the inlined 8-byte
percent_encode_indexand converts the remaining hot tails.What changed
%(and+in form-urlencoded). Dense%XXruns decode five triplets per 16-byte load (SSSE3pshufb+maddubs, or NEONtbl).static_assertthat every table matchesbit_at). SIMD classify is noinline and only runs when the remaining suffix is at least 48 bytes, so SetHash / UserInfo / the officialpercent_encodeexamples stay on scalarbit_at.to_string()appends encoded keys/values in one pass, mapping space to+instead of percent-encode thenreplace.Local results
ctest --output-on-failure --test-dir build: 345/345 passed (g++ 13.3, Debug).Release, g++ 13.3, same inputs vs
mainat 18ca958 (wall-clock, noisy):mainpercent_decodeof 80×%3Aform_urlencoded_decode(prefix + dense%XX++)percent_encodetiny (hello world)percent_encode~200-byte fragmenturl_search_params::to_string(dense keys/values)No public signature or object-layout change. New
form_urlencoded_encode/form_urlencoded_encode_appendare internal (ada::unicode).Closes #1120.