Skip to content

Find an operation without walking the document - #123

Merged
rasuvaeff merged 1 commit into
masterfrom
perf/index-operations-for-matching
Sep 6, 2026
Merged

Find an operation without walking the document#123
rasuvaeff merged 1 commit into
masterfrom
perf/index-operations-for-matching

Conversation

@rasuvaeff

Copy link
Copy Markdown
Owner

Class C of the full-cycle review (docs/reviews/review-openapi-contract-2026-09-06-full-cycle.md), findings C-1 and C-2.

C-1. Matching scanned every operation and every one of its servers per request — 0.83 ms on a thousand-operation document, identical for a hit and for a miss, since nothing stopped early.

              before      after
   50 ops:   0.053 ms   0.014 ms
  250 ops:   0.210 ms   0.009 ms
 1000 ops:   0.829 ms   0.006 ms

Routes are bucketed by method, segment count and first literal segment. Each key is a property matchPath() checks before anything else — equal segment counts, a literal equal to the decoded request segment — so a bucket miss skips work that would have been discarded anyway. Templated first segments sit in an always-scanned bucket.

Selection is unchanged by construction, not by hope: candidates are sorted by a comparator ending on the unique operation key, so the outcome never depended on collection order. The first attempt bucketed by method and segment count only and came out slower — a document where every path has the same shape lands in one bucket and pays the index for nothing. That measurement is what led to the first-segment key.

A benchmark pins the property against the lookup a consumer would write by hand over operations(): 1.63 µs versus 225 µs on the same document. A new test pins the bucketing edges — templated first segment, percent-encoded literal, a server base that prefixes the route.

C-2. examples/ had one script for thirteen public types. Two more: gate-a-request.php (validate in, hand on, validate out — the shape a PSR-15 middleware takes, over a multi-file fromFile() document) and budgets.php (Limits, and why *.body.too_large is a refusal to read).

Verification: composer build, composer rector, bin/package-audit green; corpus current (290 cases); mutation 2222 killed / 160 escaped, MSI 93% against a gate of 92 — the two new escapes widen bucketing, which cannot change a verdict, and are classified in AGENTS.md.

@coderabbitai

coderabbitai Bot commented Sep 6, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 9c8d9543-8aff-462e-a099-62353771babc

Warning

Your free Security trial is over. An organization admin can upgrade to Advanced for continuous pull request security review or dismiss this notice.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Matching scanned every operation and every one of its servers on every request:
a thousand-operation document cost 0.83 ms per validated message, the same for
a hit as for a miss, because nothing stopped early. Routes are now bucketed by
method, by segment count and by first literal segment — each one a property
`matchPath()` checks before anything else, so a bucket miss skips exactly the
work that would have been thrown away.

Selection cannot change: candidates are ordered by a comparator that ends on
the operation key, keys are unique, so the winner never depended on the order
they were collected in. Routes whose first segment is templated sit in an
always-scanned bucket, and a literal one is compared in its decoded form, which
is the form matching compares.

A thousand operations went from 0.83 ms to 0.006 ms per request, and the cost
no longer grows with the document. The benchmark pins it against the lookup a
consumer would write by hand over `operations()`.

Two examples join the package: the shape a PSR-15 middleware takes over a
multi-file document, and what the budgets on `Limits` do.
@rasuvaeff
rasuvaeff force-pushed the perf/index-operations-for-matching branch from 48665bb to c23c0c7 Compare September 6, 2026 17:02
@rasuvaeff
rasuvaeff merged commit 5edc8b1 into master Sep 6, 2026
10 checks passed
@rasuvaeff
rasuvaeff deleted the perf/index-operations-for-matching branch September 6, 2026 17:07
@rasuvaeff rasuvaeff mentioned this pull request Sep 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant