Repository navigation
Observe points without per-point allocation - #34
Merged
Merged
Conversation
zzylol
force-pushed
the
feat/experiment-results
branch
from
October 19, 2026 17:33
016efad to
82a6d7e
Compare
zzylol
force-pushed
the
perf/observe-without-allocation
branch
2 times, most recently
from
October 19, 2026 20:15
ab6f04b to
74a8594
Compare
zzylol
force-pushed
the
feat/experiment-results
branch
2 times, most recently
from
October 19, 2026 20:16
26ac19d to
123d82f
Compare
zzylol
force-pushed
the
perf/observe-without-allocation
branch
from
October 19, 2026 20:16
74a8594 to
f3d2ad5
Compare
zzylol
force-pushed
the
feat/experiment-results
branch
from
October 19, 2026 20:16
123d82f to
af506b2
Compare
zzylol
force-pushed
the
perf/observe-without-allocation
branch
2 times, most recently
from
October 19, 2026 20:16
971825f to
11092ab
Compare
zzylol
force-pushed
the
feat/experiment-results
branch
from
October 19, 2026 20:16
af506b2 to
034fe62
Compare
zzylol
force-pushed
the
perf/observe-without-allocation
branch
from
October 19, 2026 20:17
11092ab to
21f5802
Compare
zzylol
force-pushed
the
feat/experiment-results
branch
2 times, most recently
from
October 19, 2026 20:17
21f5da0 to
f8e6762
Compare
zzylol
force-pushed
the
perf/observe-without-allocation
branch
2 times, most recently
from
October 19, 2026 20:18
05ea8f8 to
bfbdb55
Compare
zzylol
force-pushed
the
feat/experiment-results
branch
2 times, most recently
from
October 19, 2026 20:18
90f57dd to
f91377d
Compare
zzylol
force-pushed
the
perf/observe-without-allocation
branch
2 times, most recently
from
October 19, 2026 20:18
541925f to
7da0bc7
Compare
zzylol
force-pushed
the
feat/experiment-results
branch
2 times, most recently
from
October 19, 2026 20:19
3a78cd7 to
402cbc3
Compare
zzylol
force-pushed
the
perf/observe-without-allocation
branch
2 times, most recently
from
October 19, 2026 20:19
c03faab to
26e7bb2
Compare
zzylol
force-pushed
the
feat/experiment-results
branch
from
October 19, 2026 20:19
402cbc3 to
0e430b8
Compare
The sketch branch spent 4.1 us per point before the sketch saw it: decoding allocated every label as new strings, the per-attribute split copied each point again, and observe cloned the whole config, took three locks and built a fresh series-key string. - codec: decode_each walks the OTAP view and rewrites one observation per point; decode_pdata_to_observations is built on it. - matchers: per_attribute writes each split into a reused observation; write_series_key fills a reused buffer and skips sorting labels that are already sorted. - precompute: the config is shared through an Arc; window and stats sit under one lock. - The sketch and exact branches both use decode_each. Per point on a pinned core (top-k, 100k Zipf routes, CMS 4x512): decode 2.02 -> 1.09 us, split 1.14 -> 0.33 us, observe 0.98 -> 0.29 us. Live top-k stack: sketch branch 0.158 -> 0.075 cores, exact branch 0.095 -> 0.064 cores.
…es once The split timing no longer clones every key into a vector inside the timed run; the keys for the CMS-only timing are collected in a separate untimed pass. A new series is inserted with the entry API instead of insert then get_mut, and the series-key writers are crate-private.
zzylol
force-pushed
the
perf/observe-without-allocation
branch
from
October 20, 2026 23:24
26e7bb2 to
30cc1fb
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The per-point cost of the sketch branch. Base: main (the experiment-results PR below it was taken out of the stack to be rerun).
Why
On the live top-k stack the sketch branch used more CPU than the exact and raw branches (0.16 vs 0.10 and 0.01 cores at 20,000 points/s per source). A per-step timing of the branch's path showed that the Count-Min + heap update was only 0.24 of 4.1 µs per point. The rest went on building owned copies of every point:
observecloned the whole config (including aHashMap<String, f64>), took three locks, and built a new series-key string per point.What changes
codec::decode_eachwalks the OTAP view and rewrites one reusedObservationper data point, passing it to a callback.decode_pdata_to_observationsis now built on it, with the same output.matchers::per_attributewrites each split into a reusedObservation, again through a callback.write_series_keyfills a reused buffer and skips sorting labels that are already sorted (same bytes as before).PrecomputeImplshares its config through anArcand keeps window and stats under one lock.asap_sketchesandexact_branchboth usedecode_each, so the sketch and exact pipelines still decode the same way.Behaviour changes on bad input:
sketch.typeor a bad envelope payload) now keeps the points observed before it; previously the whole batch was dropped. The batch's remaining points are dropped and the error is logged.observeerror is logged once per batch instead of once per point.Before → after
Per point, on one pinned core of a 56-core x86 server (400,000 top-k points: 100,000 Zipf routes, Count-Min 4 × 512 + top-10 heap; three identical runs). The before column comes from the same harness ported to the parent commit, which builds owned observations instead of calling
decode_each. In these runs the timed split also cloned every key for the CMS-only timing, which moved about 0.05 µs fromobserveto the split; the harness now collects those keys in an untimed pass. The total is unaffected:observe, including Count-Min + heapOn the live top-k stack (2 × 20,000 points/s, 2-minute average per stage), CPU cores per branch:
The sketch branch now costs about 0.01 cores more than the exact branch, roughly the Count-Min + heap update itself. Window completion delay is unchanged (sketch 5.8 s, exact 5.2 s).
Verification
cargo test --release --features otap-engine branch_phase_costs -- --ignored --nocaptureprints the table above. It is an ignored test inotap/processor.rs.per_attributewith a reused buffer gives the same observations as before.cargo fmt --check,cargo clippy --all-targets --features otap-engine,stream-benchmark -- -D warningsandcargo test --features otap-engine,stream-benchmark(the CI commands) pass at this PR's head.