Skip to content

Thread SpanPrototype through span construction (parked until dense store)#11834

Draft
dougqh wants to merge 1 commit into
dougqh/span-prototypefrom
dougqh/span-prototype-construction
Draft

Thread SpanPrototype through span construction (parked until dense store)#11834
dougqh wants to merge 1 commit into
dougqh/span-prototypefrom
dougqh/span-prototype-construction

Conversation

@dougqh

@dougqh dougqh commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Draft — PARKED. Stacked on #11828. Do not merge before the dense store.

Increment 2a of the SpanPrototype work: threads a spanPrototype through CoreSpanBuilder (mirroring tagLedger — field, startImpl, both startSpan overloads, buildSpan, buildSpanContext, reset) and applies it at buildSpanContext right after defaultSpanTags (before the per-span ledger, so per-span tags override the prototype's constants). Adds CoreSpanBuilder.withSpanPrototype(...).

Why parked

The construction-seed's payoff is a copy-down, which only beats per-span N-set when the copy is cheap. On today's bucketed OptimizedTagMap it isn't — the per-mechanism micro (on #11828) showed copy() of a 4-entry map losing to 4 set(cachedEntry) (≈295M/243M vs 417M ops/s), with identical 104 B/op across all arms. The win is dense-store-gated: a contiguous positional layout makes copy-down an arraycopy, and drops the alloc.

So this lands with/after the dense store, where touching the critical span-creation path arrives with a demonstrable win rather than a flat change. Because SpanPrototype rides the existing TagMap.copy/setAllTags API (not dense internals), the wiring auto-cashes-in when the dense store lands — no surface change, no penalty to holding.

Safety

Additive: SpanPrototype.NONE default at every threaded site → the applied branch is skipped and every existing span-creation path is byte-for-byte unchanged. CoreSpanBuilderTest (25) + CoreTracerTest2 (15) green.

Remaining (when unparked)

  • Public startSpan/buildSpan(SpanPrototype, …) entry points (additive overloads, delegate existing → NONE).
  • The 4-arm SpanStartBenchmark ({startSpan, buildSpan} × {old afterStart, new prototype}) to characterize the dispatch-level delta on the dense store.

🤖 Generated with Claude Code

…bing)

Threads a spanPrototype through the span builder exactly like tagLedger — field
+ startImpl + both startSpan overloads + buildSpan + buildSpanContext + reset —
and applies it at buildSpanContext right after defaultSpanTags (before the
per-span ledger, so per-span tags override the prototype's constants). Adds
CoreSpanBuilder.withSpanPrototype(...) as the setter.

Additive: defaults to SpanPrototype.NONE at every site, so the applied branch is
skipped and every existing span-creation path is byte-for-byte unchanged.
CoreSpanBuilderTest (25) + CoreTracerTest2 (15) green.

Next: public startSpan/buildSpan(SpanPrototype, ...) entry points + the
old-vs-new SpanStartBenchmark (which exercises the seeding end-to-end).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dougqh dougqh added the tag: no release notes Changes to exclude from release notes label Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tag: no release notes Changes to exclude from release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant