perf: widen simple-absolute http(s) parse fast path - #1199
Conversation
Strengthen try_parse_simple_absolute with bulk host/rest scanning (NEON where available), memchr delimiter locate, fail-closed host/path checks, and a cheap digit/IPv6 peek so pure IP inputs skip the fast path. Fill url components and the aggregator buffer directly on success. No string pool or href cache in this change.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1199 +/- ##
=======================================
Coverage 61.06% 61.06%
=======================================
Files 38 38
Lines 6939 6943 +4
Branches 3231 3239 +8
=======================================
+ Hits 4237 4240 +3
- Misses 749 752 +3
+ Partials 1953 1951 -2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Merging this PR will improve performance by 10.01%
Performance Changes
Tip Curious why this is faster? Comment Comparing Footnotes
|
|
clangcl (Debug) failed with gtest discovery timeout (5s) on This looks like Windows Debug discovery flakiness under load rather than a hang in CodSpeed for this PR is green with improvements and no IPv4 aggregator regressions. |
There was a problem hiding this comment.
Pull request overview
This PR widens Ada’s existing try_parse_simple_absolute fast path for absolute http/https URLs (no base URL) to validate and materialize components more efficiently, aiming to reduce overhead in common “already-normalized” inputs while fail-closing to the full state machine for edge cases (credentials, IP literals, punycode, and dot-segment normalization triggers).
Changes:
- Adds bulk host scanning and bulk “rest” validation (NEON where available), plus
memchr-based?/#location to reduce per-byte branching in the hot path. - Tightens fast-path eligibility and fallthrough conditions (credentials/port rejection, IPv4/punycode checks, dot-segment /
%2epath normalization detection). - Extends test coverage for fast-path fallthrough and correctness around credentials and IPv4-like host edge cases.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| tests/basic_tests.cpp | Adds regressions/coverage for credentialed URLs and additional simple-absolute fast-path edge cases. |
| src/parser.cpp | Implements widened simple-absolute http(s) fast path with bulk scanning/validation and direct component/buffer filling. |
| src/implementation.cpp | Documents why try_parse should not be redundantly called from parse() due to performance regressions on non-simple inputs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Lowercase domain host chars only (no uppercase). 1 = continue, 0 = stop. | ||
| // Used for the common already-normalized path (~99% of web URLs). | ||
| constexpr std::array<uint8_t, 256> k_host_clean = []() consteval { |
CMake 4.x POST_BUILD discovery under clang-cl Debug sometimes yields empty JSON and fails the build. PRE_TEST defers listing to ctest and is reliable for our static Windows test links. Also set DISCOVERY_TIMEOUT explicitly.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
src/parser.cpp:53
k_restis now unused in this file (the fast path usesrest_is_clean/k_rest_okinstead). Leaving an unusedconstexprtable at namespace scope can trigger-Wunused-const-variablewarnings in some builds; either remove it or mark it[[maybe_unused]].
// 0 = ok, 1 = ?/#, 2 = reject. '%' is allowed (already-encoded); "%2e" is
// checked later via path_needs_norm so serialization stays exact.
constexpr std::array<uint8_t, 256> k_rest = []() consteval {
std::array<uint8_t, 256> t{};
| const uint8x8_t nib = vshrn_n_u16(vreinterpretq_u16_u8(bad), 4); | ||
| const uint64_t bits = vget_lane_u64(vreinterpret_u64_u8(nib), 0); | ||
| if (bits != 0) { | ||
| return i + (size_t(__builtin_ctzll(bits)) >> 2); | ||
| } |
Summary
Widen the existing
try_parse_simple_absolutehot path for absolutehttp/https(no base URL):memchrlocate for?/#is_ipv4, punycode) and path./../%2erejection[peek so pure IPv4/IPv6 inputs never enter the fast pathOn success, fill
urlcomponents and theurl_aggregatorbuffer directly (no freelist, no href cache).Scope
src/parser.cpp,tests/basic_tests.cpp, small comment insrc/implementation.cppstring_pool, nourlhref cache, no public API signature changesIndependence
Targets
mainonly. Independent of the get-href and href-cache PRs (not stacked).Test plan
basic_testssimple-absolute casesbenchdatafilter for aggregator/url href