Repository navigation
perf(metrics): gather timeslice ragged values from a per-slice index - #58
Merged
Oseltamivir merged 1 commit intoOct 19, 2026
Conversation
_compute_timeslices called _compute_results once per slice, and each call gathered list-metric (ragged) values with get_values_for_mask, which scans every stored value. Export cost was O(slices x values). Bucket each ragged column's values by slice once with a stable sort, so a slice reads only its own values, in the same storage order as the mask path. Exported results and timeslices are unchanged. Signed-off-by: weireweire <20922698+weireweire@users.noreply.github.com>
Try out this PRQuick install: pip install --upgrade --force-reinstall git+https://github.com/ai-dynamo/aiperf.git@e2569e3d128479944d49b7c454d7fcb6dfd671b9Recommended with virtual environment (using uv): uv venv --python 3.12 && source .venv/bin/activate
uv pip install --upgrade --force-reinstall git+https://github.com/ai-dynamo/aiperf.git@e2569e3d128479944d49b7c454d7fcb6dfd671b9Last updated for commit: |
|
Thanks for the contribution! |
4 of 5 tasks
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.
Summary
Make timeslice export linear in the number of stored list-metric values. Each slice now reads only its own
inter_chunk_latencyvalues from an index built once per export, instead of scanning every stored value. Exported results and timeslices are byte-for-byte unchanged.Cause
export_results(src/aiperf/metrics/accumulator.py:767) computes timeslices wheneverslice_durationis set. Theagentxpreset sets it to 1 s._compute_timeslices(accumulator.py:798) loops over every slice (:859) and calls_compute_resultsfor each one (:875)._compute_results->_collect_scalars_and_arrays(:429) ->_collect_one_list_column(:508) ->RaggedSeries.get_values_for_mask(:543).get_values_for_mask(src/aiperf/metrics/ragged_series.py:81) builds a boolean mask over all V stored values and gathers from it.Fix
_build_slice_ragged_indexassigns each value its record's slice, stable-sorts once per ragged column, and records each slice's range withsearchsorted._collect_one_list_columntakes a slice's values asvalues[order[start:end]]. The stable sort keeps storage order within a slice, so the array matchesget_values_for_mask(full_mask)element for element, and sums and percentiles are bitwise equal.Measurements
Saved records from a 3,600 s, concurrency-4096 AgentX run were replayed into
MetricsAccumulator: 549,835 records, 161.5 Minter_chunk_latencyvalues, 3,596 one-second slices, one CPU core.export_results(3,596 slices)export_results, first 20 K records (171 slices)The exported
resultsand all timeslices were compared throughmodel_dump(). They are identical at 20 K records and at the full set. In the same run the client spent more than an hour between the end of profiling and the final export.Tests
TestTimesliceRaggedIndex(2 cases: unscoped, and phase-scoped with warmup records). It ingests 400 records with shuffled start times, empty lists, and starts on slice edges. It checks that the timeslice path no longer callsget_values_for_maskand that the export is byte-identical to the per-slice mask path.tests/unit: 17,659 passed and 2 failed. Both failures also fail onmaster(test_completed_excludes_analyzer_metrics,test_every_numeric_field_has_bounds).pre-commit runon the changed files passes, including check-ergonomics and check-ruff-baselined.This complements #55: if timeslices become opt-in, runs that opt in still get a linear export.
Note
Medium Risk
Changes hot-path timeslice aggregation math for list metrics; behavior is intended to be identical but regressions would affect exported percentiles and sums on long AgentX runs.
Overview
Timeslice export for replay-capable ragged metrics (e.g.
inter_chunk_latency) no longer scans all stored list values on every slice. Once per_compute_timeslicesrun,_build_slice_ragged_indexbuckets each value by its record’s time bin (stable sort +searchsortedranges). While each slice is computed,_collect_one_list_columngathers that slice viavalues[order[start:end]]instead ofRaggedSeries.get_values_for_mask, with transient_slice_ragged_index/_active_slice_bincleared in afinallyblock. The per-slice loop moves into_compute_timeslice_bins; overall summary and non-replay backends still use the mask path.Tests add
TestTimesliceRaggedIndex: randomized ingest checks that timeslice export barely callsget_values_for_maskand matches byte-identical JSON to the legacy mask path (with and without phase scoping).Reviewed by Cursor Bugbot for commit e2569e3. Bugbot is set up for automated code reviews on this repo. Configure here.