caddy/modules/caddyhttp/rewrite
Julien Voisin 49d7187c1b
caddyhttp: presize buffers in hot paths to reduce allocations (#7842)
* caddyhttp: presize buffers in hot paths to reduce allocations

Right-size three per-request allocations that previously grew from a
nil/empty backing array, causing repeated reallocation:

- CleanPath: pre-Grow the strings.Builder used when slash collapsing is
  disabled, instead of letting it reallocate as runes are appended
- headers: presize the rewritten value slice in HeaderOps.ApplyTo's Set
  loop instead of appending from nil
- reverseproxy: presize the weights slice in WeightedRoundRobinSelection
  .Select

This commit also adds benchmarks exercising each path. Measured with benchstat
with count=20 and GOMAXPROCS=1, with p=0.000:

                                    sec/op                  B/op              allocs/op
CleanPathNoCollapse       1013.4n -> 828.6n  (-18.23%)  120->64  (-46.67%)   4->1  (-75.00%)
HeaderOpsApplyToSet       1262.0n -> 955.8n  (-24.27%)  255->152 (-40.39%)   9->6  (-33.33%)
WeightedRoundRobinSelect   215.8n -> 200.3n  ( -7.20%)  112->96  (-14.29%)   2->2  (N/A)

* caddyhttp: presize strings.Builder in query rewrite and path matcher

Two builders whose output size is bounded by a known input length were
growing from empty, causing repeated reallocation. Seed each with a
capacity hint:

- rewrite.buildQueryString: pre-Grow to len(qs) (runs per request when
  rewrite query manipulation is configured)
- MatchPath.matchPatternWithEscapeSequence: pre-Grow to len(escapedPath)
  (reached only when a path pattern contains % escape sequences)

Adds a benchmark for buildQueryString, measured with benchstat:

BuildQueryString:
	- sec/op  965.2n -> 743.3n  (-22.99%)
	- B/op 248->80  (-67.74%)
	- allocs/op 5->1  (-80.00%)

The builder previously reallocated four times per call. The matcher path
is cold and not separately benchmarked.

* chore: add benchmark headers

---------

Signed-off-by: Julien Voisin <jvoisin@users.noreply.github.com>
(cherry picked from commit c8492563ee)
2026-11-04 18:05:11 -05:00
..
caddyfile.go chore: Dumb `prealloc` lint fix (#7430) 2026-01-13 14:13:43 -05:00
rewrite.go caddyhttp: presize buffers in hot paths to reduce allocations (#7842) 2026-11-04 18:05:11 -05:00
rewrite_bench_test.go caddyhttp: presize buffers in hot paths to reduce allocations (#7842) 2026-11-04 18:05:11 -05:00
rewrite_test.go rewrite: treat only valid percent encodings as escapes (#8345) 2026-11-03 18:21:22 -05:00