perf(router): replace matchit with a registration-ordered route table - #137
Open
RomainLanz wants to merge 2 commits into
Open
perf(router): replace matchit with a registration-ordered route table#137RomainLanz wants to merge 2 commits into
RomainLanz wants to merge 2 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
AI assistance was used to draft parts of the implementation, tests, benchmarks, and PR description.
Hey! 👋🏻
This PR replaces the runtime
@poppinss/matchitdependency with an internal, registration-ordered route table.It addresses the same linear route-matching cost as #135, but explores a different architecture. Instead of keeping
matchitbehind multiple indexes, this implementation moves matching itself into a persistent route table.How it works
The route table combines:
Mapfast path for exact static routes;matching route always wins;
(
global,sticky, or overriddenexec/testmethods).The structural index only eliminates impossible routes. It never changes route precedence.
matchRoute, which receives a transient list of patterns, keeps a flat matching path instead of constructing a temporary index.The public routes tree and
StoreMethodNodeshape remain unchanged.Compatibility
Registration order remains part of the routing semantics, including precedence between:
Compatibility was checked with 1,603,716 differential comparisons against
matchit, covering generated route patterns, route permutations, domains, wildcards, optionals, casts, decoding, stateful regexes, and custom regex methods.matchitremains a dev dependency only, as the differential-test oracle. No production source or built output imports it.Benchmarks
All measurements below compare the previous matcher and this implementation on the same machine and environment.
Full-stack HTTP: dynamic and wildcard routes
Protocol: 5 rounds, 3 seconds warmup, 5 seconds measurement, 100 connections, pipelining 10.
Both scenarios passed functional validation with no errors or timeouts.
Full-stack HTTP: static routes
Protocol: 5 rounds, 10 seconds warmup, 10 seconds measurement, 100 connections, pipelining 10.
The first-route result is within the relatively high variance of this exploratory run and should not be treated as a demonstrated regression.
These static measurements were collected after the static-index commit. The final matcher preserves that exact static
Mapfast path, but a final-state 40s/40s run is still planned.Matcher microbenchmarks
With 1,000 routes:
The overlapping-regex case is intentionally included as an adversarial scenario where the tree cannot eliminate any candidate.
Costs
Measured while building indexes for 10,000 routes:
The additional work happens when routes are committed and is amortized across requests.