perf: reuse duplicate rolling lookbacks
This commit is contained in:
@@ -688,7 +688,17 @@ impl AdjustedCloseSeries {
|
|||||||
end: usize,
|
end: usize,
|
||||||
lookbacks: &[usize; N],
|
lookbacks: &[usize; N],
|
||||||
) -> [Option<f64>; N] {
|
) -> [Option<f64>; N] {
|
||||||
std::array::from_fn(|index| self.moving_average_at_end(end, lookbacks[index]))
|
let mut values = [None; N];
|
||||||
|
for index in 0..N {
|
||||||
|
if let Some(previous) =
|
||||||
|
(0..index).find(|previous| lookbacks[*previous] == lookbacks[index])
|
||||||
|
{
|
||||||
|
values[index] = values[previous];
|
||||||
|
} else {
|
||||||
|
values[index] = self.moving_average_at_end(end, lookbacks[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
values
|
||||||
}
|
}
|
||||||
|
|
||||||
fn moving_average_at_end(&self, end: usize, lookback: usize) -> Option<f64> {
|
fn moving_average_at_end(&self, end: usize, lookback: usize) -> Option<f64> {
|
||||||
@@ -5399,6 +5409,81 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore = "manual release-mode duplicate rolling lookback benchmark"]
|
||||||
|
fn benchmark_adjusted_close_reuses_duplicate_lookbacks() {
|
||||||
|
use std::hint::black_box;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
let data = volume_contract_data(Some([1.0, 1.0, 1.0]));
|
||||||
|
let symbol_id = data.symbol_id("000001.SZ").expect("symbol id");
|
||||||
|
let series = data
|
||||||
|
.adjusted_close_series_by_symbol_id(symbol_id)
|
||||||
|
.expect("adjusted close series");
|
||||||
|
let lookbacks = [1usize, 2, 3, 1, 2, 3, 1];
|
||||||
|
let end = 3usize;
|
||||||
|
let iterations = 3_000_000usize;
|
||||||
|
let mut repeated_nanos = 0u128;
|
||||||
|
let mut reused_nanos = 0u128;
|
||||||
|
let mut repeated_checksum = 0.0;
|
||||||
|
let mut reused_checksum = 0.0;
|
||||||
|
|
||||||
|
for sample in 0..6 {
|
||||||
|
let measure_repeated = || {
|
||||||
|
let started = Instant::now();
|
||||||
|
let mut checksum = 0.0;
|
||||||
|
for _ in 0..iterations {
|
||||||
|
let values = std::array::from_fn::<_, 7, _>(|index| {
|
||||||
|
series.moving_average_at_end(black_box(end), black_box(lookbacks[index]))
|
||||||
|
});
|
||||||
|
checksum += black_box(values).into_iter().flatten().sum::<f64>();
|
||||||
|
}
|
||||||
|
(started.elapsed().as_nanos(), checksum)
|
||||||
|
};
|
||||||
|
let measure_reused = || {
|
||||||
|
let started = Instant::now();
|
||||||
|
let mut checksum = 0.0;
|
||||||
|
for _ in 0..iterations {
|
||||||
|
checksum += black_box(
|
||||||
|
series.moving_averages_at_end(black_box(end), black_box(&lookbacks)),
|
||||||
|
)
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.sum::<f64>();
|
||||||
|
}
|
||||||
|
(started.elapsed().as_nanos(), checksum)
|
||||||
|
};
|
||||||
|
let (baseline, candidate) = if sample % 2 == 0 {
|
||||||
|
(measure_repeated(), measure_reused())
|
||||||
|
} else {
|
||||||
|
let candidate = measure_reused();
|
||||||
|
let baseline = measure_repeated();
|
||||||
|
(baseline, candidate)
|
||||||
|
};
|
||||||
|
repeated_nanos += baseline.0;
|
||||||
|
repeated_checksum += baseline.1;
|
||||||
|
reused_nanos += candidate.0;
|
||||||
|
reused_checksum += candidate.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(repeated_checksum, reused_checksum);
|
||||||
|
let repeated_seconds = repeated_nanos as f64 / 1_000_000_000.0;
|
||||||
|
let reused_seconds = reused_nanos as f64 / 1_000_000_000.0;
|
||||||
|
eprintln!(
|
||||||
|
"{}",
|
||||||
|
serde_json::json!({
|
||||||
|
"schemaVersion": "fidc-adjusted-close-duplicate-lookback-benchmark/v1",
|
||||||
|
"samples": 6,
|
||||||
|
"iterationsPerSample": iterations,
|
||||||
|
"lookbacks": lookbacks,
|
||||||
|
"repeatedSeconds": repeated_seconds,
|
||||||
|
"reusedSeconds": reused_seconds,
|
||||||
|
"speedup": repeated_seconds / reused_seconds,
|
||||||
|
"checksum": repeated_checksum,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore = "manual component benchmark"]
|
#[ignore = "manual component benchmark"]
|
||||||
fn benchmark_daily_snapshot_view_lookup() {
|
fn benchmark_daily_snapshot_view_lookup() {
|
||||||
|
|||||||
Reference in New Issue
Block a user