Repository navigation
Conversation
Removing iterates the headers with an iterator it allocates, once per injected header, though the header is usually not there yet. Probe with lastHeader, which doesn't allocate, and remove only on a hit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🟢 Java Benchmark SLOs — All performance SLOs passed
PR vs. master results
Commit: Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
More details
Both Kafka adapters retain duplicate-header replacement and read-only exceptions, preserving the producer’s retry with writable headers.
🤖 Bits Code Review · Commit 722d664
Kafka / consumer-benchmarkParameters
See matching parameters
SummaryFound 0 performance improvements and 0 performance regressions! Performance is the same for 3 metrics, 0 unstable metrics. See unchanged results
|
What Does This Do
When Kafka producers inject trace context, each header is now removed first only if it's already on the record. Before, every injected header went through
headers.remove(key), which iterates with an iterator it allocates, though on an outgoing record the header is usually not there yet. NowlastHeader(key), which loops by index and doesn't allocate, probes first.Behavior doesn't change:
ot-baggage-headers (span baggage, the end-to-end start time). A second write still replaces the first, leaving one header.addthrowsIllegalStateExceptionasremovedid, so the producer's retry with a writable copy of the record still runs.Motivation
A JFR profile of
kafka-producer-perf-testunder the agent showedArrayList.iterator()at 4.5% of allocation, most of it from this setter, which runs for every injected header on every send.KafkaInjectBenchmark(new) injects a span into newRecordHeaders(JDK 17, 3 forks, per inject):spanBaggageThat's 192 B less per send, and 256 B with span baggage, where the replacing write still removes. The machine was busy (load 7–15), so treat the times as approximate; they're flat or slightly better.
Additional Notes
ot-baggage-headers, since two codecs write them.value.getBytes(UTF_8)still copies each value. Removing it needs a way for codecs to write header values straight into bytes.TextMapInjectAdapterTest, in both client modules, covers adding, replacing, setting the same key twice and read-only headers. It passes against the old setter too.🤖 Generated with Claude Code