Skip to content

Commit

Permalink
Merge pull request #112 from the8472/opt-quantiles
Browse files Browse the repository at this point in the history
Optimize quantile_below, 100x speedup
  • Loading branch information
jonhoo authored Aug 13, 2022
2 parents 5854b2e + 857870f commit a732bab
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 3 deletions.
19 changes: 19 additions & 0 deletions benches/quantiles.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#![feature(test)]

extern crate test;

use hdrhistogram::*;
use test::{black_box, Bencher};

#[bench]
fn quantiles_below(b: &mut Bencher) {
let mut h = Histogram::<u32>::new_with_bounds(1, 100_000, 3).unwrap();
for i in 0..100_000 {
h.record(i).unwrap();
}

b.iter(|| {
black_box(h.quantile_below(black_box(10)));
black_box(h.quantile_below(black_box(90_000)));
})
}
24 changes: 21 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1378,9 +1378,27 @@ impl<T: Counter> Histogram<T> {

let target_index = self.index_for_or_last(value);
// TODO use RangeInclusive when it's stable to avoid checked_add
let total_to_current_index = (0..target_index.checked_add(1).expect("usize overflow"))
.map(|i| self.count_at_index(i).expect("index is <= last_index()"))
.fold(0_u64, |t, v| t.saturating_add(v.as_u64()));
let end = target_index.checked_add(1).expect("usize overflow");
// count the smaller half
let (slice, lower) = if target_index < self.counts.len() / 2 {
(&self.counts[0..end], true)
} else {
(&self.counts[end..], false)
};
let iter = slice.iter().map(Counter::as_u64);

let total_to_current_index = if self.total_count < u64::MAX {
// if the total didn't saturate then any partial count shouldn't either.
// iter::sum optimizes better than the saturating_add fallback below
iter.sum::<u64>()
} else {
iter.fold(0u64, u64::saturating_add)
};
let total_to_current_index = if lower {
total_to_current_index
} else {
self.total_count - total_to_current_index
};
total_to_current_index.as_f64() / self.total_count as f64
}

Expand Down

0 comments on commit a732bab

Please sign in to comment.