• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ruby-grape / grape / 25213900833 / 17
97%
master: 97%

Build:
Build:
LAST BUILD BRANCH: robust_mounted_app_comparison
DEFAULT BRANCH: master
Ran 01 May 2026 12:16PM UTC
Files 154
Run time 5s
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

01 May 2026 12:14PM UTC coverage: 95.643% (+0.007%) from 95.636%
25213900833.17

Pull #2696

github

ericproulx
Reduce per-request allocations on the request hot path

A bundle of small, behavior-preserving cleanups that drop allocations
or chain walks from every request. Stable values (filter buckets,
versioner options, etc.) are computed once at compile/init and read via
`attr_reader`, instead of being re-resolved through nested hash lookups
on every request.

* `Endpoint#run`: precompute filter buckets (befores, before_validations,
  after_validations, afters, finallies) and `:build_params_with` once
  in `compile!`; replace the dynamic `define_method` accessor block
  with `attr_reader`; remove a dead `header 'Allow', header['Allow']`
  self-assignment.

* `Versioner::Base`: replace the two `define_method`-per-key blocks
  (top-level and `version_options` keys) with `attr_reader` plus ivars
  precomputed in `initialize`. Per-request `pattern`/`prefix`/`vendor`/
  `strict`/etc. lookups now hit attr loads.

* `Request#make_params`: skip the `except(:version, :route_info)` hash
  allocation in the common case where routing args contain only the
  known keys.

* `Validators::Base#validate!`: lazy-allocate `array_errors`. Saves one
  Array allocation per validator per request when validation succeeds.

* `InheritableValues#[]`: drop the per-call merge with `Hash#fetch`
  plus a fallback block. Lookup is 1.55x faster microbenched, allocates
  zero. Mostly helps boot/compile time (where ~30+ reads per endpoint
  hit this).

* `Grape::API::Instance`: rename `ROOT_PREFIX_VERSIONING_KEY` to
  `ROOT_PREFIX_VERSIONING_KEYS` (it holds 3 symbols), pair via `zip`
  instead of `each_with_index` + manual indexing.

* `Validations::Types::CustomTypeCoercer#infer_coercion_method`:
  guard-clause refactor of the nested if/else.

End-to-end, 3-run averaged on Ruby 4.0.3, arm64-darwin25, against
`/api/v1/hello` returning a small JSON object:

                       no-yjit       yjit
  master HEAD:         52,088 i/s    101,563 i/s
  master + this PR:    57,433 i/s    107,982 i/... (continued)
Pull Request #2696: Reduce per-request allocations on the request hot path

1051 of 1161 branches covered (90.53%)

Branch coverage included in aggregate %.

3317 of 3406 relevant lines covered (97.39%)

1013.15 hits per line

Source Files on job run-3.2-gemfiles/rack_2_2.gemfile - 25213900833.17
  • Tree
  • List 154
  • Changed 9
  • Source Changed 9
  • Coverage Changed 6
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Build 25213900833
  • 4c868253 on github
  • Prev Job for on perf/request-hot-path-polish (#25137726391.5)
  • Next Job for on perf/request-hot-path-polish (#25214109046.4)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc