Skip to content

feat: single-pass value_at_percentiles / values_at_quantiles batch API (7.2x)#138

Open
fcostaoliveira wants to merge 1 commit into
HdrHistogram:mainfrom
fcostaoliveira:perf/value-at-percentiles-batch
Open

feat: single-pass value_at_percentiles / values_at_quantiles batch API (7.2x)#138
fcostaoliveira wants to merge 1 commit into
HdrHistogram:mainfrom
fcostaoliveira:perf/value-at-percentiles-batch

Conversation

@fcostaoliveira

Copy link
Copy Markdown

Summary

Add single-pass batch queries:

  • values_at_quantiles(&[f64]) -> Vec<u64>
  • value_at_percentiles(&[f64]) -> Vec<u64>

They resolve N quantiles/percentiles in one scan over counts[] instead of N separate
value_at_quantile calls. Requested quantiles are resolved in ascending-target order; the next
target is hoisted into a local so the hot loop stays a tight
total += counts[i]; if total >= next_target (the same shape as the singular scan) — per-crossing
bookkeeping runs only when a threshold is actually reached. Results are returned in input order.

Benchmark

Getting all 7 of {50,75,90,95,99,99.9,99.99}, single core (Intel Granite Rapids):

calls/sec µs/call
value_at_percentile 24,896 40.2
value_at_percentiles (this PR) 178,326 5.6

+616% (7.2×).

Correctness

  • Results byte-identical to per-quantile value_at_quantile / value_at_percentile, verified for
    both sorted and unsorted inputs including the 0.0 / 100.0 edges.
  • record and the singular query paths are unchanged.

Happy to add doc examples and a criterion/#[bench] entry if you'd like.

fcostaoliveira pushed a commit to redis-performance/hdr-agent-workspace that referenced this pull request Jul 2, 2026
…+7.2x (PR #138)

Race-driven optimizations of the Go and Rust ports (submodules kept at official tips; wins
on fork branches + PRs):
- GO-EXP-001: flat counts[] scan in ValueAtPercentile — +133% (0.0457->0.1066 Mq/s), gnr1
  same-session A/B, go test green, results byte-identical. PR HdrHistogram/hdrhistogram-go#57.
- RUST-EXP-001: single-pass value_at_percentiles/values_at_quantiles batch API — +616% (7.2x)
  over 7x singular (24.9K->178.3K calls/sec). v1 naive was slower; v2 hoisted next-target ->
  tight loop. bsink byte-identical. PR HdrHistogram/HdrHistogram_rust#138.
Logged EXPERIMENTS.md + RACE.md (progress + post-opt standings) + memory.
Add batch queries that resolve N quantiles/percentiles in ONE scan over counts[], instead
of N separate value_at_quantile calls. Requested quantiles are resolved in ascending-target
order; the next target is hoisted into a local so the hot loop stays a tight
'total += counts[i]; if total >= next_target' (same shape as the singular scan).

Naming matches the existing value_at_quantile/value_at_percentile pair; both new methods are
#[must_use]. Results are byte-identical to per-quantile calls including unsorted/duplicate
inputs, q==0.0/1.0, q>1.0 clamp, and empty histograms (verified by tests). NaN quantiles do
not panic (the sort is over the derived u64 targets, not the f64 inputs).

Batch throughput for all 7 of {50,75,90,95,99,99.9,99.99} (Granite Rapids, single core):
178,326 calls/sec vs 24,896 for 7x value_at_percentile = +616% (7.2x).
@fcostaoliveira fcostaoliveira force-pushed the perf/value-at-percentiles-batch branch from 96fa8ab to 26e3d39 Compare July 2, 2026 14:07
@fcostaoliveira

Copy link
Copy Markdown
Author

Updated to address review: renamed values_at_quantilesvalue_at_quantiles for consistency with the value_at_* pair; added #[must_use] on both; documented the empty-histogram/clamp/q==0 behavior; and added tests asserting the batch equals per-item value_at_quantile/value_at_percentile across unsorted + duplicate inputs, q==0.0/1.0, q>1.0, and an empty histogram. cargo fmt --check clean; the new code has no clippy warnings.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant