use beachcomber::cache::Cache;
use beachcomber::provider::{ProviderResult, Value};
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use std::sync::Arc;
use std::thread;
fn bench_cache_read_global(c: &mut Criterion) {
let cache = Cache::new();
let mut result = ProviderResult::new();
result.insert("name", Value::String("testhost".to_string()));
result.insert("short", Value::String("test".to_string()));
cache.put("hostname", None, result);
c.bench_function("cache_read_global", |b| {
b.iter(|| {
let entry = cache.get("hostname", None);
criterion::black_box(entry);
})
});
}
fn bench_cache_read_path_scoped(c: &mut Criterion) {
let cache = Cache::new();
let mut result = ProviderResult::new();
result.insert("branch", Value::String("main".to_string()));
result.insert("dirty", Value::Bool(false));
cache.put("git", Some("/home/user/project"), result);
c.bench_function("cache_read_path_scoped", |b| {
b.iter(|| {
let entry = cache.get("git", Some("/home/user/project"));
criterion::black_box(entry);
})
});
}
fn bench_cache_write(c: &mut Criterion) {
let cache = Cache::new();
c.bench_function("cache_write", |b| {
b.iter(|| {
let mut result = ProviderResult::new();
result.insert("name", Value::String("testhost".to_string()));
cache.put("hostname", None, result);
})
});
}
fn bench_cache_read_contention(c: &mut Criterion) {
let cache = Arc::new(Cache::new());
let mut result = ProviderResult::new();
result.insert("name", Value::String("testhost".to_string()));
cache.put("hostname", None, result);
let mut group = c.benchmark_group("cache_read_contention");
for num_threads in [1, 4, 8, 16] {
group.bench_with_input(
BenchmarkId::from_parameter(num_threads),
&num_threads,
|b, &num_threads| {
b.iter(|| {
let handles: Vec<_> = (0..num_threads)
.map(|_| {
let cache = Arc::clone(&cache);
thread::spawn(move || {
for _ in 0..100 {
let entry = cache.get("hostname", None);
criterion::black_box(entry);
}
})
})
.collect();
for h in handles {
h.join().unwrap();
}
})
},
);
}
group.finish();
}
fn bench_cache_field_extraction(c: &mut Criterion) {
let cache = Cache::new();
let mut result = ProviderResult::new();
result.insert("branch", Value::String("main".to_string()));
result.insert("dirty", Value::Bool(false));
result.insert("ahead", Value::Int(2));
result.insert("behind", Value::Int(0));
result.insert("staged", Value::Int(0));
result.insert("unstaged", Value::Int(3));
result.insert("untracked", Value::Int(1));
result.insert("conflicted", Value::Int(0));
result.insert("stash", Value::Int(0));
result.insert("state", Value::String("clean".to_string()));
cache.put("git", Some("/project"), result);
let mut group = c.benchmark_group("cache_field_extraction");
group.bench_function("full_provider", |b| {
b.iter(|| {
let entry = cache.get("git", Some("/project")).unwrap();
criterion::black_box(entry.result.to_json());
})
});
group.bench_function("single_field", |b| {
b.iter(|| {
let entry = cache.get("git", Some("/project")).unwrap();
let val = entry.result.get("branch").unwrap();
criterion::black_box(val.as_text());
})
});
group.finish();
}
criterion_group!(
benches,
bench_cache_read_global,
bench_cache_read_path_scoped,
bench_cache_write,
bench_cache_read_contention,
bench_cache_field_extraction,
);
criterion_main!(benches);