Skip to content

Add span-creation JMH benchmarks (front-half allocation)#11915

Draft
dougqh wants to merge 2 commits into
masterfrom
dougqh/span-creation-bench
Draft

Add span-creation JMH benchmarks (front-half allocation)#11915
dougqh wants to merge 2 commits into
masterfrom
dougqh/span-creation-bench

Conversation

@dougqh

@dougqh dougqh commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

What

Adds application-thread ("front-half") allocation benchmarks for the full span-creation lifecycle (create → tag → finish), to ground the TagMap 2.0 / SpanPrototype allocation work against the real span path.

  • SpanCreationBenchmark — single span. Bare baseline (startSpan vs buildSpan), two known-tag shapes set after start — web-server (7 tags) and JDBC/DB client (9 tags) — plus a builder-tag-path arm (withTag before start(), the OTel-bridge shape).
  • TraceAssemblyBenchmark — web-shape root + N children (childCount 1/5/20), exercising the per-span baseline-tag copy that map-to-map copy (TagMap 1.0) and the trace/span tag split (level-split) target.
  • SpanCreationVirtualThreadBenchmarkstartSpan on a virtual thread (JDK 21+ via reflection), the regime where SpanBuilder reuse is disabled.
  • DropWriter — shared no-op Writer so finish() excludes serialization / agent I/O, isolating front-half allocation for -prof gc.

Why

gc.alloc.rate.norm (B/op) is deterministic and is the primary signal; throughput is directional. The benchmarks are deliberately drift-stable (only API byte-identical v1.53→master), so the same file can be grafted onto past release tags to reconstruct a historical allocation curve.

Notes

  • Measurement infrastructure only — no product change.
  • Run with -prof gc, and force tracer logging to WARN (unsuppressed DEBUG logging allocates and corrupts the numbers).

🤖 Generated with Claude Code

dougqh and others added 2 commits July 10, 2026 14:27
Adds application-thread (front-half) allocation benchmarks that ground the
TagMap 2.0 / SpanPrototype work against the real span lifecycle:

- SpanCreationBenchmark (front-A): single span create -> tag -> finish. Bare
  baseline (startSpan vs buildSpan), two known-tag shapes set after start —
  web-server (7 tags) and JDBC/DB client (9 tags) — plus a builder-tag-path arm
  (withTag before start, the OTel-bridge shape) to track how the startSpan /
  buildSpan lineages diverge across releases.
- TraceAssemblyBenchmark (front-B): web-shape root + N children (childCount
  1/5/20), exercising the per-span baseline-tag copy that map-to-map copy
  (TagMap 1.0) and the trace/span tag split (level-split) target.
- DropWriter: shared no-op Writer so finish() excludes serialization / agent
  I/O, isolating front-half allocation for -prof gc.

Deliberately drift-stable (v1.53->master API) so the same file can be grafted
onto old release tags for a historical allocation curve.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Runs startSpan create+finish on a virtual thread — the regime the platform-thread
SpanCreationBenchmark is blind to. startSpan's thread-local SpanBuilder reuse
(#9537) is disabled on virtual threads, so a builder is allocated per span there;
the builder bypass (#9998) removes it. This bench is where that difference shows.

Starts the virtual thread via reflection (Thread.startVirtualThread) so the jmh
source set still compiles on pre-21 toolchains; requires a 21+ JDK at run time.
The per-op vthread spawn/join cost is constant across tracer versions, so it
cancels in the version-over-version delta.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dougqh dougqh added comp: core Tracer core type: refactoring tag: no release note tag: ai generated Largely based on code generated by an AI or LLM labels Jul 10, 2026
@dd-octo-sts

dd-octo-sts Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

🟢 Java Benchmark SLOs — All performance SLOs passed

Suite Status
Startup 🟢 pass

SLO thresholds are defined here based on automatically generated metrics. A warning is raised when results are within 5% of the threshold.

PR vs. master results
Scenario Candidate master Δ (95% CI of mean)
startup:insecure-bank:iast:Agent 13.98 s 13.87 s [+0.1%; +1.5%] (maybe worse)
startup:insecure-bank:tracing:Agent 12.86 s 12.96 s [-1.3%; -0.2%] (maybe better)
startup:petclinic:appsec:Agent 16.87 s 16.82 s [-0.5%; +1.1%] (no difference)
startup:petclinic:iast:Agent 17.04 s 17.11 s [-1.3%; +0.4%] (no difference)
startup:petclinic:profiling:Agent 16.70 s 16.99 s [-2.7%; -0.6%] (maybe better)
startup:petclinic:sca:Agent 16.95 s 16.74 s [+0.1%; +2.4%] (maybe worse)
startup:petclinic:tracing:Agent 15.70 s 16.10 s [-6.8%; +1.7%] (no difference)

Commit: cfa94f1e · CI Pipeline · Benchmarking Platform UI


Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: core Tracer core tag: ai generated Largely based on code generated by an AI or LLM tag: no release note type: refactoring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant