perf(router): compile dynamic parameter extraction - #32
Conversation
Benchmark d’intégration — toutes les optimisations HTTPJ’ai assemblé localement, sans pousser de branche d’intégration, les têtes de Méthode : même orb et même suite que le baseline initial, Node 24.19, serveur CPU 2, autocannon CPU 4/6, 3 répétitions, chauffe 2 s + mesure 5 s, ordre randomisé. Tous les runs retenus ont 0 erreur, 0 timeout et 0 non-2xx.
Comparaison dans le même run final :
Conclusion honnête : le cumul apporte un gros saut et dépasse Adonis dans plusieurs cas, mais ne dépasse pas encore Nest/Fastify hors POST. Par rapport à l’intégration précédente |
Reuse registration-order route arrays and backtrack over one parameter object instead of allocating intermediate copies during dynamic matching. Snapshot parameters only when handlers are emitted so middleware and monitor handlers remain isolated. Amp-Thread-ID: https://ampcode.com/threads/T-01a019cf-991c-74c8-9d37-1a285cd5f912 Co-authored-by: Upd4ting <upd4ting@gmail.com>
aa93ca3 to
70fb83b
Compare
🔗 Linked issue
N/A
❓ Type of change
📚 Description
Compile the dynamic-segment extraction shape when a handler is registered:
dynamicRouteList, avoidingObject.values(dynamicRoutes)allocation on every lookup;This head is rebased on combined
mainat04f8294and preserves:src/implementations/api/index.tshas no incremental diff);Static → dynamic → catch-all precedence, method →
anyfallback, regex generation, URL encoding behavior, middleware ordering, and response/context behavior are unchanged.Rebased benchmark
Environment: Node 22.19.0, one isolated orb, autocannon 8.0.0.
04f82942a366614128538dbf9e469aa6d8b74426(perf(api): compile request controller resolution #29 + perf(server): skip empty middleware work #30 + perf(router): index exact static handlers #31)70fb83be1bc80c5aaf1551163c70c0a2be23ea3d(perf(api): compile request controller resolution #29 + perf(server): skip empty middleware work #30 + perf(router): index exact static handlers #31 + perf(router): compile dynamic parameter extraction #32)Micro-router — 8 alternating runs
The fixture registers static, simple/complex/concurrent/catch-all routes and 1,000 late-match dynamic routes. Timed loops use 20m operations for exact static, 3m simple, 1m complex/concurrent/catch-all, and 5k for the 1,000-route late match, after 100k warm-up operations. CV is across the 8 process-level runs. Allocation values are V8 statistical sampling estimates and are comparative, not a full allocation census.
/users/:idA separate static-only exact-index benchmark (no dynamic fixture, 50m operations, 10 alternating runs) measures +2.3% for the candidate: 54.01m → 55.23m ops/s, 18.59 → 18.14 ns/op, CV 5.8% → 4.3%. The −6.3% mixed-fixture result above is therefore reported as a fixture/cache-pressure anomaly, not hidden. The full HTTP static result below is also positive.
Full HTTP stack — 6 alternating runs
50 connections, 1 s warm-up + 2 s measured per scenario/run. This includes exact-index lookup where applicable, sockets, URL parsing, context/response creation, handler execution, and response serialization.
/users/:idDoes #32 recover #31's ~4–7% dynamic regression?
Memory / allocation limits
Ten alternating
--expose-gcregistration runs for 1,000 dynamic routes measured retained heap delta of 2,901,366 bytes on main versus 2,964,190 bytes on the candidate: +62,824 bytes / +2.2% (about 63 bytes per registered route in this fixture). This is the cost of the additional ordered route arrays/references.V8 sampled allocation estimates fall substantially on every dynamic lookup (for example 53.20 → 0.15 B/op simple and 78.23 → 23.59 B/op at 1,000 routes), but sampling is statistical and these values must not be read as exact total allocations.
Validation after rebase
pnpm install --frozen-lockfilepnpm buildpnpm test— 140 passingpnpm lint— clean, no warningsorigin/main: onlysrc/server.tsandsrc/test/routing-parameters.test.tsCoverage includes static/dynamic/catch-all precedence, multiple and patterned captures, encoded values, concurrent branch backtracking,
any, multi-handler object isolation, prefix/postfix/monitor parameters, and unregister/re-register lifecycle. Existing #29–#31 test suites remain green.Limits / risks
📝 Checklist