use std::time::Duration;
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use rand::{Rng, SeedableRng};
use sqlitegraph::{EdgeSpec, GraphConfig, NeighborQuery, NodeSpec, SnapshotId, open_graph};
mod bench_utils;
use bench_utils::{BENCHMARK_SIZES, create_benchmark_temp_dir};
const SAMPLE_SIZE: usize = 1000; const WARM_UP_TIME: Duration = Duration::from_secs(5);
const MEASURE_TIME: Duration = Duration::from_secs(15);
#[cfg(feature = "memory_profiling")]
fn bench_memory_usage(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("memory_profiling");
group.sample_size(100);
group.warm_up_time(Duration::from_secs(2));
group.measurement_time(Duration::from_secs(10));
group.bench_function("memory_per_1000_nodes", |b| {
b.iter(|| {
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");
for i in 0..1000 {
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");
}
std::hint::black_box(&graph);
});
});
group.finish();
}
fn bench_get_node(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("single_node_ops");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
for &size in BENCHMARK_SIZES {
group.bench_with_input(BenchmarkId::new("get_node", size), &size, |b, &size| {
b.iter(|| {
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::new();
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);
}
let lookup_id = node_ids[size / 2];
let _node = graph
.get_node(SnapshotId::current(), lookup_id)
.expect("Failed to get node");
});
});
}
group.finish();
}
fn bench_get_neighbors_small(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("single_node_ops");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
group.bench_function("get_neighbors_small_10_edges", |b| {
b.iter(|| {
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 center = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: "center".to_string(),
file_path: None,
data: serde_json::json!({"center": true}),
})
.expect("Failed to insert center node");
for i in 0..10 {
let leaf = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: format!("leaf_{}", i),
file_path: None,
data: serde_json::json!({"leaf": i}),
})
.expect("Failed to insert leaf node");
graph
.insert_edge(EdgeSpec {
from: center,
to: leaf,
edge_type: "star".to_string(),
data: serde_json::json!({}),
})
.expect("Failed to insert edge");
}
let _neighbors = graph
.neighbors(SnapshotId::current(), center, NeighborQuery::default())
.expect("Failed to get neighbors");
});
});
group.finish();
}
fn bench_get_neighbors_medium(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("single_node_ops");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
group.bench_function("get_neighbors_medium_100_edges", |b| {
b.iter(|| {
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 center = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: "center".to_string(),
file_path: None,
data: serde_json::json!({"center": true}),
})
.expect("Failed to insert center node");
for i in 0..100 {
let leaf = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: format!("leaf_{}", i),
file_path: None,
data: serde_json::json!({"leaf": i}),
})
.expect("Failed to insert leaf node");
graph
.insert_edge(EdgeSpec {
from: center,
to: leaf,
edge_type: "star".to_string(),
data: serde_json::json!({}),
})
.expect("Failed to insert edge");
}
let _neighbors = graph
.neighbors(SnapshotId::current(), center, NeighborQuery::default())
.expect("Failed to get neighbors");
});
});
group.finish();
}
fn bench_get_neighbors_large(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("single_node_ops");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
group.bench_function("get_neighbors_large_1000_edges", |b| {
b.iter(|| {
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 center = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: "center".to_string(),
file_path: None,
data: serde_json::json!({"center": true}),
})
.expect("Failed to insert center node");
for i in 0..1000 {
let leaf = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: format!("leaf_{}", i),
file_path: None,
data: serde_json::json!({"leaf": i}),
})
.expect("Failed to insert leaf node");
graph
.insert_edge(EdgeSpec {
from: center,
to: leaf,
edge_type: "star".to_string(),
data: serde_json::json!({}),
})
.expect("Failed to insert edge");
}
let _neighbors = graph
.neighbors(SnapshotId::current(), center, NeighborQuery::default())
.expect("Failed to get neighbors");
});
});
group.finish();
}
fn bench_bfs_depth_1(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("traversal_workloads");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
for &size in [100, 500, 1000].iter() {
group.bench_with_input(BenchmarkId::new("bfs_depth_1", size), &size, |b, &size| {
b.iter(|| {
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::new();
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 - 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");
}
let _bfs_result = graph
.bfs(SnapshotId::current(), node_ids[0], 1)
.expect("Failed to perform BFS");
});
});
}
group.finish();
}
fn bench_bfs_depth_3(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("traversal_workloads");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
for &size in [100, 500, 1000].iter() {
group.bench_with_input(BenchmarkId::new("bfs_depth_3", size), &size, |b, &size| {
b.iter(|| {
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::new();
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 - 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");
}
let _bfs_result = graph
.bfs(SnapshotId::current(), node_ids[0], 3)
.expect("Failed to perform BFS");
});
});
}
group.finish();
}
fn bench_bfs_depth_5(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("traversal_workloads");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
for &size in [100, 500, 1000].iter() {
group.bench_with_input(BenchmarkId::new("bfs_depth_5", size), &size, |b, &size| {
b.iter(|| {
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::new();
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 - 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");
}
let _bfs_result = graph
.bfs(SnapshotId::current(), node_ids[0], 5)
.expect("Failed to perform BFS");
});
});
}
group.finish();
}
fn bench_k_hop_10_nodes(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("traversal_workloads");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
group.bench_function("k_hop_10_nodes", |b| {
b.iter(|| {
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::new();
for i in 0..100 {
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);
}
let mut rng = rand::rngs::StdRng::seed_from_u64(0x5F3759DF);
for _ in 0..200 {
let from_idx = rng.gen_range(0..100);
let to_idx = rng.gen_range(0..100);
if from_idx != to_idx {
graph
.insert_edge(EdgeSpec {
from: node_ids[from_idx],
to: node_ids[to_idx],
edge_type: "random".to_string(),
data: serde_json::json!({}),
})
.expect("Failed to insert edge");
}
}
let mut total_visited = 0;
for i in 0..10 {
let start_node = node_ids[i * 10];
let bfs_result = graph
.bfs(SnapshotId::current(), start_node, 2)
.expect("Failed to perform BFS");
total_visited += bfs_result.len();
}
assert!(total_visited > 0, "Should visit some nodes");
});
});
group.finish();
}
fn bench_cache_hit_sequential(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("cache_performance");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
group.bench_function("cache_hit_sequential", |b| {
b.iter(|| {
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::new();
for i in 0..100 {
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..99 {
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");
}
for i in 0..100 {
let _neighbors = graph
.neighbors(SnapshotId::current(), node_ids[i], NeighborQuery::default())
.expect("Failed to get neighbors");
}
});
});
group.finish();
}
fn bench_cache_hit_random(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("cache_performance");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
group.bench_function("cache_hit_random", |b| {
b.iter(|| {
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::new();
for i in 0..100 {
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..99 {
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");
}
let mut rng = rand::rngs::StdRng::seed_from_u64(0x5F3759DF);
for _ in 0..100 {
let idx = rng.gen_range(0..100);
let _neighbors = graph
.neighbors(
SnapshotId::current(),
node_ids[idx],
NeighborQuery::default(),
)
.expect("Failed to get neighbors");
}
});
});
group.finish();
}
fn bench_cache_eviction(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("cache_performance");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
group.bench_function("cache_eviction", |b| {
b.iter(|| {
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::new();
for i in 0..1000 {
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 1..1000 {
graph
.insert_edge(EdgeSpec {
from: node_ids[0],
to: node_ids[i],
edge_type: "star".to_string(),
data: serde_json::json!({}),
})
.expect("Failed to insert edge");
}
for i in 0..500 {
let _neighbors = graph
.neighbors(SnapshotId::current(), node_ids[i], NeighborQuery::default())
.expect("Failed to get neighbors");
}
});
});
group.finish();
}
fn bench_iterate_compressed(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("compression_performance");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
group.bench_function("iterate_compressed", |b| {
b.iter(|| {
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 center = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: "center".to_string(),
file_path: None,
data: serde_json::json!({"center": true}),
})
.expect("Failed to insert center node");
for i in 0..1000 {
let leaf = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: format!("leaf_{}", i),
file_path: None,
data: serde_json::json!({"leaf": i}),
})
.expect("Failed to insert leaf node");
graph
.insert_edge(EdgeSpec {
from: center,
to: leaf,
edge_type: "star".to_string(),
data: serde_json::json!({}),
})
.expect("Failed to insert edge");
}
let _neighbors = graph
.neighbors(SnapshotId::current(), center, NeighborQuery::default())
.expect("Failed to get neighbors");
});
});
group.finish();
}
fn bench_decompress_overhead(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("compression_performance");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
group.bench_function("decompress_overhead", |b| {
b.iter(|| {
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 center = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: "center".to_string(),
file_path: None,
data: serde_json::json!({"center": true}),
})
.expect("Failed to insert center node");
for i in 0..1000 {
let leaf = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: format!("leaf_{}", i),
file_path: None,
data: serde_json::json!({"leaf": i}),
})
.expect("Failed to insert leaf node");
graph
.insert_edge(EdgeSpec {
from: center,
to: leaf,
edge_type: "star".to_string(),
data: serde_json::json!({}),
})
.expect("Failed to insert edge");
}
for _ in 0..10 {
let _neighbors = graph
.neighbors(SnapshotId::current(), center, NeighborQuery::default())
.expect("Failed to get neighbors");
}
});
});
group.finish();
}
fn bench_cache_hit_ratio_bfs(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("cache_validation");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
group.bench_function("cache_hit_ratio_bfs_depth_3", |b| {
b.iter(|| {
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::new();
for i in 0..100 {
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..99 {
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");
}
let _bfs_result = graph
.bfs(SnapshotId::current(), node_ids[0], 3)
.expect("Failed to perform BFS");
});
});
group.finish();
}
fn bench_high_degree_cache_retention(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("cache_validation");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
group.bench_function("high_degree_cache_retention", |b| {
b.iter(|| {
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 hub = graph
.insert_node(NodeSpec {
kind: "Hub".to_string(),
name: "hub".to_string(),
file_path: None,
data: serde_json::json!({"hub": true}),
})
.expect("Failed to insert hub node");
for i in 0..1000 {
let leaf = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: format!("leaf_{}", i),
file_path: None,
data: serde_json::json!({"leaf": i}),
})
.expect("Failed to insert leaf node");
graph
.insert_edge(EdgeSpec {
from: hub,
to: leaf,
edge_type: "star".to_string(),
data: serde_json::json!({}),
})
.expect("Failed to insert edge");
}
let mut rng = rand::rngs::StdRng::seed_from_u64(0x5F3759DF);
for _ in 0..1000 {
let _node = graph
.get_node(SnapshotId::current(), rng.gen_range(1..1001))
.expect("Failed to get node");
}
let _hub_neighbors = graph
.neighbors(SnapshotId::current(), hub, NeighborQuery::default())
.expect("Failed to get hub neighbors");
});
});
group.finish();
}
fn bench_prefetch_bfs(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("cache_validation");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
group.bench_function("prefetch_bfs_depth_3", |b| {
b.iter(|| {
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::new();
for i in 0..100 {
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..99 {
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");
}
let _bfs_result = graph
.bfs(SnapshotId::current(), node_ids[0], 3)
.expect("Failed to perform BFS");
});
});
group.finish();
}
fn bench_compression_ratio(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("compression_validation");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
group.bench_function("compression_ratio_sequential_ids", |b| {
b.iter(|| {
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 center = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: "center".to_string(),
file_path: None,
data: serde_json::json!({"center": true}),
})
.expect("Failed to insert center node");
for i in 0..1000 {
let leaf = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: format!("leaf_{}", i),
file_path: None,
data: serde_json::json!({"leaf": i}),
})
.expect("Failed to insert leaf node");
graph
.insert_edge(EdgeSpec {
from: center,
to: leaf,
edge_type: "star".to_string(),
data: serde_json::json!({}),
})
.expect("Failed to insert edge");
}
let _neighbors = graph
.neighbors(SnapshotId::current(), center, NeighborQuery::default())
.expect("Failed to get neighbors");
});
});
group.finish();
}
fn bench_decompress_overhead_comparison(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("compression_validation");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
group.bench_function("decompress_overhead_1000_edges", |b| {
b.iter(|| {
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 center = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: "center".to_string(),
file_path: None,
data: serde_json::json!({"center": true}),
})
.expect("Failed to insert center node");
for i in 0..1000 {
let leaf = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: format!("leaf_{}", i),
file_path: None,
data: serde_json::json!({"leaf": i}),
})
.expect("Failed to insert leaf node");
graph
.insert_edge(EdgeSpec {
from: center,
to: leaf,
edge_type: "star".to_string(),
data: serde_json::json!({}),
})
.expect("Failed to insert edge");
}
for _ in 0..10 {
let _neighbors = graph
.neighbors(SnapshotId::current(), center, NeighborQuery::default())
.expect("Failed to get neighbors");
}
});
});
group.finish();
}
fn bench_cache_line_utilization(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("compression_validation");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
group.bench_function("cache_line_utilization_compressed", |b| {
b.iter(|| {
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 center = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: "center".to_string(),
file_path: None,
data: serde_json::json!({"center": true}),
})
.expect("Failed to insert center node");
for i in 0..1000 {
let leaf = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: format!("leaf_{}", i),
file_path: None,
data: serde_json::json!({"leaf": i}),
})
.expect("Failed to insert leaf node");
graph
.insert_edge(EdgeSpec {
from: center,
to: leaf,
edge_type: "star".to_string(),
data: serde_json::json!({}),
})
.expect("Failed to insert edge");
}
let _neighbors = graph
.neighbors(SnapshotId::current(), center, NeighborQuery::default())
.expect("Failed to get neighbors");
});
});
group.finish();
}
fn bench_compression_roundtrip(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("compression_validation");
group.sample_size(SAMPLE_SIZE);
group.warm_up_time(WARM_UP_TIME);
group.measurement_time(MEASURE_TIME);
group.bench_function("compression_roundtrip_correctness", |b| {
b.iter(|| {
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 center = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: "center".to_string(),
file_path: None,
data: serde_json::json!({"center": true}),
})
.expect("Failed to insert center node");
for i in 0..100 {
let leaf = graph
.insert_node(NodeSpec {
kind: "Node".to_string(),
name: format!("leaf_{}", i),
file_path: None,
data: serde_json::json!({"leaf": i}),
})
.expect("Failed to insert leaf node");
let edge_data = if i % 3 == 0 {
serde_json::json!({"idx": i})
} else if i % 3 == 1 {
serde_json::json!({"idx": i, "data": "test".repeat(10)})
} else {
serde_json::json!(null)
};
graph
.insert_edge(EdgeSpec {
from: center,
to: leaf,
edge_type: "test".to_string(),
data: edge_data,
})
.expect("Failed to insert edge");
}
let neighbors = graph
.neighbors(SnapshotId::current(), center, NeighborQuery::default())
.expect("Failed to get neighbors");
assert_eq!(neighbors.len(), 100, "Should retrieve all 100 neighbors");
std::hint::black_box(neighbors);
});
});
group.finish();
}
criterion_group!(
benches,
bench_get_node,
bench_get_neighbors_small,
bench_get_neighbors_medium,
bench_get_neighbors_large,
bench_bfs_depth_1,
bench_bfs_depth_3,
bench_bfs_depth_5,
bench_k_hop_10_nodes,
bench_cache_hit_sequential,
bench_cache_hit_random,
bench_cache_eviction,
bench_iterate_compressed,
bench_decompress_overhead,
bench_cache_hit_ratio_bfs,
bench_high_degree_cache_retention,
bench_prefetch_bfs,
bench_compression_ratio,
bench_decompress_overhead_comparison,
bench_cache_line_utilization,
bench_compression_roundtrip,
);
criterion_main!(benches);