Skip to content

perf: add processor hot-path benchmarks#160

Merged
devarismeroxa merged 1 commit into
mainfrom
perf/processor-benchmarks
Jul 5, 2026
Merged

perf: add processor hot-path benchmarks#160
devarismeroxa merged 1 commit into
mainfrom
perf/processor-benchmarks

Conversation

@devarismeroxa

Copy link
Copy Markdown
Contributor

Summary

This repo had zero benchmarks despite Processor.Process and reference
resolution (internal/reference) sitting on the per-record hot path for
every processor invocation. Adds committed benchmarks so future changes
to these paths have a baseline to regress against.

  • internal/reference/reference_bench_test.go:
    • BenchmarkNewResolver - one-time reference-string parse/validate cost
      (paid once, typically at Configure).
    • BenchmarkResolver_Resolve - per-record resolve + Get(), covering
      raw vs. structured payloads, top-level fields (.Key,
      .Payload.After), metadata fields (plain and bracket-indexed), and
      structured sub-fields (including nested).
    • BenchmarkResolver_ResolveAndSet - per-record resolve + Set(),
      the pattern used by field-set/rename-style processors.
  • processor_func_bench_test.go:
    • BenchmarkProcessorFunc_Process_MetadataFieldSet and
      BenchmarkProcessorFunc_Process_StructuredFieldSet - a
      representative field-set processor built on ProcessorFunc (the
      SDK's only concrete, reusable Processor implementation), exercising
      a full 100-record batch Process call end to end.

The SDK itself ships no concrete field-set/rename processor (those live
in the main conduit repo), so the Process-level benchmark uses
ProcessorFunc wired to the same resolve-then-set pattern real
processors use — the closest thing to "a representative processor" that
this repo actually exposes.

No production code changed.

Numbers (Apple M3 Max, go test -bench . -benchmem -benchtime 2s ./...)

Reference resolution (per record, after NewResolver is done once):

Benchmark ns/op B/op allocs/op
Resolve .Key (raw) 3.5 0 0
Resolve .Key (structured) 3.4 0 0
Resolve .Metadata.field (raw) 40.8 40 2
Resolve .Metadata.field (structured) 39.5 40 2
Resolve .Payload.After (raw) 5.4 0 0
Resolve .Payload.After (structured) 5.4 0 0
Resolve .Payload.After.status (structured) 31.6 48 1
Resolve .Payload.After.customer.name (structured, nested) 93.8 120 3
Resolve+Set .Metadata.field (raw) 31.4 24 1
Resolve+Set .Metadata.field (structured) 30.7 24 1
Resolve+Set .Payload.After.status (structured) 34.4 48 1
Resolve+Set .Payload.After.customer.name (structured, nested) 101.7 120 3

NewResolver (paid once per reference string, not per record): 210 ns –
720 ns, 3–11 allocs, depending on reference depth.

ProcessorFunc.Process on a 100-record batch:

Benchmark ns/op (batch) ns/op (per record) B/op allocs/op
MetadataFieldSet / Raw 11,296 ~113 26,592 301
MetadataFieldSet / Structured 11,619 ~116 26,592 301
StructuredFieldSet (nested) / Structured 18,262 ~183 36,192 501

Test plan

  • go build ./...
  • go test ./... -count=1
  • go test ./... -count=1 -race
  • golangci-lint run ./... - 0 issues
  • GOOS=wasip1 GOARCH=wasm go build ./... - WASM build unaffected
  • go test -bench . -benchmem -benchtime 2s ./... - all benchmarks pass, numbers above

🤖 Generated with Claude Code

https://claude.ai/code/session_01Tapg9dLWXKMZJoL65R24vd

The SDK had zero benchmarks despite reference resolution and Process
being on the per-record hot path for every processor. Adds:

- internal/reference: BenchmarkNewResolver (one-time parse cost),
  BenchmarkResolver_Resolve, and BenchmarkResolver_ResolveAndSet
  (per-record resolve/get/set cost), covering raw and structured
  payloads, top-level and nested structured fields, and bracket-index
  metadata keys.
- BenchmarkProcessorFunc_Process_MetadataFieldSet and
  BenchmarkProcessorFunc_Process_StructuredFieldSet: a representative
  field-set processor built on ProcessorFunc (the SDK's only concrete,
  reusable Processor implementation), exercising a full batch Process
  call end to end.

These establish a baseline for catching per-record regressions; no
production code changed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tapg9dLWXKMZJoL65R24vd
@devarismeroxa devarismeroxa requested a review from a team as a code owner July 5, 2026 21:39
@devarismeroxa devarismeroxa merged commit 6441632 into main Jul 5, 2026
3 checks passed
@devarismeroxa devarismeroxa deleted the perf/processor-benchmarks branch July 5, 2026 21:42
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