use criterion::{BenchmarkId, Criterion, black_box, criterion_group, criterion_main};
use sqlitegraph::sharding::*;
use sqlitegraph::{GraphEntity, SqliteGraph};
use std::time::Duration;
fn bench_csr_construction_scale(c: &mut Criterion) {
let mut group = c.benchmark_group("csr_scale_construction");
group.measurement_time(Duration::from_secs(5));
group.sample_size(10);
for edge_count in [1_000, 10_000, 100_000, 500_000].iter() {
group.bench_with_input(
BenchmarkId::from_parameter(edge_count),
edge_count,
|b, &edge_count| {
b.iter(|| {
let mut shard = CsrShard::new(0, 1000, 1000 + edge_count as u32);
for i in 0..edge_count {
let edge = CsrEdge {
src: 1000 + (i % 10000) as u32, dst: 2000 + i as u32,
weight: 0.5,
flags: 0,
};
shard.add_edge(edge);
}
shard.sort_edges();
black_box(shard.edge_count())
});
},
);
}
group.finish();
}
fn bench_snapshot_stats_scale(c: &mut Criterion) {
let mut group = c.benchmark_group("snapshot_stats_scale");
group.measurement_time(Duration::from_secs(5));
group.sample_size(10);
for snapshot_count in [10, 100, 1_000].iter() {
group.bench_with_input(
BenchmarkId::from_parameter(snapshot_count),
snapshot_count,
|b, &snapshot_count| {
b.iter(|| {
let graph = SqliteGraph::open_in_memory().unwrap();
for i in 0..snapshot_count {
let snapshot_id = format!("snapshot_{}", i);
let _timestamp = graph.create_snapshot(&snapshot_id).unwrap();
let entities = vec![GraphEntity {
id: 0,
kind: "Test".to_string(),
name: format!("entity_{}", i),
file_path: None,
data: serde_json::json!({"idx": i}),
}];
let _ = graph.batch_insert_entities_with_snapshot(&entities, &snapshot_id);
}
let stats = graph.query_as_of(999999999).unwrap();
black_box(stats.total_entities)
});
},
);
}
group.finish();
}
fn bench_semantic_layer_scale(c: &mut Criterion) {
let mut group = c.benchmark_group("semantic_layer_scale");
group.measurement_time(Duration::from_secs(30));
group.sample_size(10);
for embedding_count in [100, 1_000, 5_000].iter() {
group.bench_with_input(
BenchmarkId::from_parameter(embedding_count),
embedding_count,
|b, &embedding_count| {
b.iter(|| {
let mut layer = SemanticLayer::new(128);
let insert_count = embedding_count.min(50000);
for i in 0..insert_count {
let embedding: Vec<f32> =
(0..128).map(|j| (i + j) as f32 / 100000.0).collect();
layer.insert_embedding(i as u32, embedding).unwrap();
}
let query: Vec<f32> = (0..128).map(|i| i as f32 / 100000.0).collect();
let results = layer.knn_search(black_box(&query), 10);
black_box(results.len())
});
},
);
}
group.finish();
}
fn bench_property_store_scale(c: &mut Criterion) {
let mut group = c.benchmark_group("property_store_scale");
group.measurement_time(Duration::from_secs(5));
group.sample_size(10);
for token_count in [1_000, 10_000].iter() {
group.bench_with_input(
BenchmarkId::from_parameter(token_count),
token_count,
|b, &token_count| {
b.iter(|| {
let mut store = PropertyStore::in_memory().unwrap();
for i in 0..token_count {
let token_text = format!("token_{}", i % 1000); store.set_token_text(i as u32, &token_text).unwrap();
if i % 10 == 0 {
store.set_embedding(i as u32, &[0.1; 128]).unwrap();
}
}
let query_id = (token_count / 2).max(1) as u32;
let text = store.get_token_text(black_box(query_id)).unwrap();
black_box(text)
});
},
);
}
group.finish();
}
criterion_group!(
name = scale_benches;
config = Criterion::default()
.measurement_time(Duration::from_secs(5))
.sample_size(10);
targets =
bench_csr_construction_scale,
bench_snapshot_stats_scale,
bench_semantic_layer_scale,
bench_property_store_scale
);
criterion_main!(scale_benches);