use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use ri::cache::{RiMemoryCache, RiCache};
fn bench_cache_set(c: &mut Criterion) {
let mut group = c.benchmark_group("cache_set");
group.throughput(Throughput::Elements(1));
group.bench_function("set_small_value", |b| {
let rt = tokio::runtime::Runtime::new().unwrap();
let cache = RiMemoryCache::new();
b.iter(|| {
rt.block_on(async {
cache.set("key", "value", None).await.unwrap();
black_box(());
});
});
});
group.bench_function("set_medium_value", |b| {
let rt = tokio::runtime::Runtime::new().unwrap();
let cache = RiMemoryCache::new();
let medium_value = "x".repeat(100);
b.iter(|| {
rt.block_on(async {
cache.set("key", &medium_value, None).await.unwrap();
black_box(());
});
});
});
group.bench_function("set_large_value", |b| {
let rt = tokio::runtime::Runtime::new().unwrap();
let cache = RiMemoryCache::new();
let large_value = "x".repeat(10000);
b.iter(|| {
rt.block_on(async {
cache.set("key", &large_value, None).await.unwrap();
black_box(());
});
});
});
group.bench_function("set_with_ttl", |b| {
let rt = tokio::runtime::Runtime::new().unwrap();
let cache = RiMemoryCache::new();
b.iter(|| {
rt.block_on(async {
cache.set("key", "value", Some(3600)).await.unwrap();
black_box(());
});
});
});
group.finish();
}
fn bench_cache_get(c: &mut Criterion) {
let rt = tokio::runtime::Runtime::new().unwrap();
let cache = RiMemoryCache::new();
rt.block_on(async {
for i in 0..1000 {
cache.set(&format!("key_{}", i), &format!("value_{}", i), None).await.unwrap();
}
});
let mut group = c.benchmark_group("cache_get");
group.throughput(Throughput::Elements(1));
group.bench_function("get_hit", |b| {
b.iter(|| {
rt.block_on(async {
let result = cache.get("key_500").await.unwrap();
black_box(result);
});
});
});
group.bench_function("get_miss", |b| {
b.iter(|| {
rt.block_on(async {
let result = cache.get("nonexistent_key").await.unwrap();
black_box(result);
});
});
});
group.finish();
}
fn bench_cache_batch_operations(c: &mut Criterion) {
let rt = tokio::runtime::Runtime::new().unwrap();
let cache = RiMemoryCache::new();
let mut group = c.benchmark_group("cache_batch");
for size in [10, 100, 1000].iter() {
let keys: Vec<String> = (0..*size).map(|i| format!("batch_key_{}", i)).collect();
let key_refs: Vec<&str> = keys.iter().map(|s| s.as_str()).collect();
let items: Vec<(&str, &str)> = (0..*size).map(|i| {
let s = format!("batch_key_{}", i);
(Box::leak(s.into_boxed_str()) as &str, "value")
}).collect();
group.throughput(Throughput::Elements(*size as u64));
group.bench_with_input(BenchmarkId::new("get_multi", size), size, |b, _| {
b.iter(|| {
rt.block_on(async {
let result = cache.get_multi(&key_refs).await.unwrap();
black_box(result);
});
});
});
group.bench_with_input(BenchmarkId::new("set_multi", size), size, |b, _| {
b.iter(|| {
rt.block_on(async {
cache.set_multi(&items, None).await.unwrap();
black_box(());
});
});
});
}
group.finish();
}
fn bench_cache_exists(c: &mut Criterion) {
let rt = tokio::runtime::Runtime::new().unwrap();
let cache = RiMemoryCache::new();
rt.block_on(async {
for i in 0..1000 {
cache.set(&format!("exists_key_{}", i), &format!("value_{}", i), None).await.unwrap();
}
});
let mut group = c.benchmark_group("cache_exists");
group.throughput(Throughput::Elements(1));
group.bench_function("exists_true", |b| {
b.iter(|| {
rt.block_on(async {
let result = cache.exists("exists_key_500").await;
black_box(result);
});
});
});
group.bench_function("exists_false", |b| {
b.iter(|| {
rt.block_on(async {
let result = cache.exists("nonexistent_key").await;
black_box(result);
});
});
});
group.finish();
}
fn bench_cache_delete(c: &mut Criterion) {
let rt = tokio::runtime::Runtime::new().unwrap();
let mut group = c.benchmark_group("cache_delete");
group.throughput(Throughput::Elements(1));
group.bench_function("delete_existing", |b| {
b.iter(|| {
rt.block_on(async {
let cache = RiMemoryCache::new();
cache.set("delete_key", "value", None).await.unwrap();
let result = cache.delete("delete_key").await.unwrap();
black_box(result);
});
});
});
group.bench_function("delete_nonexistent", |b| {
let cache = RiMemoryCache::new();
b.iter(|| {
rt.block_on(async {
let result = cache.delete("nonexistent_key").await.unwrap();
black_box(result);
});
});
});
group.finish();
}
fn bench_cache_stats(c: &mut Criterion) {
let rt = tokio::runtime::Runtime::new().unwrap();
let cache = RiMemoryCache::new();
rt.block_on(async {
for i in 0..1000 {
cache.set(&format!("stats_key_{}", i), &format!("value_{}", i), None).await.unwrap();
}
});
let mut group = c.benchmark_group("cache_stats");
group.throughput(Throughput::Elements(1));
group.bench_function("get_stats", |b| {
b.iter(|| {
rt.block_on(async {
let stats = cache.stats().await;
black_box(stats);
});
});
});
group.finish();
}
criterion_group!(
cache_benches,
bench_cache_set,
bench_cache_get,
bench_cache_batch_operations,
bench_cache_exists,
bench_cache_delete,
bench_cache_stats,
);
criterion_main!(cache_benches);