use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};
use sqlitegraph::{EdgeSpec, GraphConfig, NodeSpec, SnapshotId, open_graph};
mod bench_utils;
use bench_utils::{MEASURE, WARM_UP, create_benchmark_temp_dir};
fn create_chain_graph(size: usize) -> (tempfile::TempDir, std::path::PathBuf, Vec<i64>) {
let temp_dir = create_benchmark_temp_dir();
let db_path = temp_dir.path().join("benchmark.db");
let graph = open_graph(&db_path, &GraphConfig::native()).expect("Failed to create graph");
let mut node_ids = Vec::with_capacity(size);
for i in 0..size {
let node_id = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: format!("node_{}", i),
file_path: None,
data: serde_json::json!({"id": i}),
})
.expect("Failed to insert node");
node_ids.push(node_id);
}
for i in 0..size.saturating_sub(1) {
graph
.insert_edge(EdgeSpec {
from: node_ids[i],
to: node_ids[i + 1],
edge_type: "chain".to_string(),
data: serde_json::json!({"order": i}),
})
.expect("Failed to insert edge");
}
(temp_dir, db_path, node_ids)
}
fn bench_memory_overhead_native(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("regression_memory_native");
group.measurement_time(MEASURE);
group.warm_up_time(WARM_UP);
for &size in &[100, 500, 1000] {
group.throughput(Throughput::Elements(size as u64));
group.bench_with_input(
BenchmarkId::new("chain_native", size),
&size,
|b, &_size| {
b.iter(|| {
let (_temp_dir, db_path, node_ids) = create_chain_graph(size);
let graph =
open_graph(&db_path, &GraphConfig::native()).expect("Failed to open graph");
let start_node = node_ids[0];
let _result = graph
.bfs(SnapshotId::current(), start_node, size as u32)
.expect("BFS traversal failed");
std::mem::forget(_temp_dir);
});
},
);
}
group.finish();
}
fn bench_memory_overhead_sqlite(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("regression_memory_sqlite");
group.measurement_time(MEASURE);
group.warm_up_time(WARM_UP);
for &size in &[100, 500, 1000] {
group.throughput(Throughput::Elements(size as u64));
group.bench_with_input(
BenchmarkId::new("chain_sqlite", size),
&size,
|b, &_size| {
b.iter(|| {
let (_temp_dir, db_path, node_ids) = create_chain_graph(size);
let graph =
open_graph(&db_path, &GraphConfig::sqlite()).expect("Failed to open graph");
let start_node = node_ids[0];
let _result = graph
.bfs(SnapshotId::current(), start_node, size as u32)
.expect("BFS traversal failed");
std::mem::forget(_temp_dir);
});
},
);
}
group.finish();
}
#[allow(dead_code)]
fn estimate_telemetry_overhead(node_count: usize) -> (usize, usize, usize) {
let cluster_buffer_max = 512 * 1024;
let offsets_size = node_count * 24;
let index_size = if node_count > 0 {
node_count * 32 } else {
0
};
(cluster_buffer_max, offsets_size, index_size)
}
criterion_group!(
benches,
bench_memory_overhead_native,
bench_memory_overhead_sqlite
);
criterion_main!(benches);