#![allow(missing_docs, reason = "Benchmark code")]
use std::collections::HashMap;
use std::hint::black_box;
use std::time::{Duration, Instant};
use anyspawn::Spawner;
use cachet::{Cache, CacheEntry, TimeToRefresh};
use cachet_tier::MockCache;
use criterion::{Criterion, criterion_group, criterion_main};
use tick::Clock;
use tokio::runtime::Runtime;
fn rt() -> Runtime {
Runtime::new().expect("failed to create runtime")
}
fn mock_with_value(key: &str, value: &str) -> MockCache<String, String> {
let mut data = HashMap::new();
data.insert(key.to_string(), CacheEntry::new(value.to_string()));
MockCache::with_data(data)
}
fn bench_refresh_overhead(c: &mut Criterion) {
let rt = rt();
let mut group = c.benchmark_group("refresh_overhead");
group.bench_function("without_refresh", |b| {
let cache = rt.block_on(async {
let clock = Clock::new_tokio();
Cache::builder(clock.clone())
.storage(mock_with_value("key", "value"))
.fallback(Cache::builder(clock).storage(MockCache::<String, String>::new()))
.build()
});
let key = "key".to_string();
b.iter_custom(|iters| {
rt.block_on(async {
let start = Instant::now();
for _ in 0..iters {
let _ = black_box(cache.get(black_box(&key)).await);
}
start.elapsed()
})
});
});
group.bench_function("with_refresh_not_triggering", |b| {
let cache = rt.block_on(async {
let clock = Clock::new_tokio();
Cache::builder(clock.clone())
.storage(mock_with_value("key", "value"))
.fallback(Cache::builder(clock).storage(MockCache::<String, String>::new()))
.time_to_refresh(TimeToRefresh::new(Duration::from_hours(1), Spawner::new_tokio()))
.build()
});
let key = "key".to_string();
b.iter_custom(|iters| {
rt.block_on(async {
let start = Instant::now();
for _ in 0..iters {
let _ = black_box(cache.get(black_box(&key)).await);
}
start.elapsed()
})
});
});
group.bench_function("with_refresh_triggering", |b| {
let cache = rt.block_on(async {
let clock = Clock::new_tokio();
Cache::builder(clock.clone())
.storage(mock_with_value("key", "value"))
.fallback(Cache::builder(clock).storage(mock_with_value("key", "refreshed")))
.time_to_refresh(TimeToRefresh::new(Duration::from_secs(0), Spawner::new_tokio()))
.build()
});
let key = "key".to_string();
b.iter_custom(|iters| {
rt.block_on(async {
let start = Instant::now();
for _ in 0..iters {
let _ = black_box(cache.get(black_box(&key)).await);
}
start.elapsed()
})
});
});
group.finish();
}
criterion_group!(benches, bench_refresh_overhead);
criterion_main!(benches);