#[path = "../tests/common/fixtures.rs"]
mod fixtures;
use std::path::PathBuf;
use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion};
use macrame::graph::{astar, dijkstra, k_core, louvain, scc};
use macrame::prelude::*;
use macrame::temporal::{hydrate_attributes, reconstruct, save_snapshot};
const TS: &str = "2026-01-01T00:00:00.000000Z";
const OPEN: &str = "9999-12-31T23:59:59.999999Z";
fn scale() -> usize {
std::env::var("MACRAME_BENCH_SCALE")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or(1)
}
fn control_conn() -> &'static (tokio::runtime::Runtime, libsql::Connection) {
static CONTROL: std::sync::OnceLock<(tokio::runtime::Runtime, libsql::Connection)> =
std::sync::OnceLock::new();
CONTROL.get_or_init(|| {
let rt = runtime();
let conn = rt.block_on(async {
let db = libsql::Builder::new_local(":memory:")
.build()
.await
.unwrap();
db.connect().unwrap()
});
(rt, conn)
})
}
fn controlled_group<'a>(
c: &'a mut Criterion,
name: &str,
) -> criterion::BenchmarkGroup<'a, criterion::measurement::WallTime> {
let mut g = c.benchmark_group(name);
g.bench_function("control/select_1", |b| {
let (rt, conn) = control_conn();
b.iter(|| {
rt.block_on(async {
let mut rows = conn.query("SELECT 1", ()).await.unwrap();
rows.next().await.unwrap().unwrap();
})
})
});
g
}
fn runtime() -> tokio::runtime::Runtime {
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap()
}
struct Fixture {
db: Database,
_dir: tempfile::TempDir,
path: PathBuf,
}
async fn fixture() -> Fixture {
let dir = tempfile::TempDir::new().unwrap();
let path = dir.path().join("bench.db");
let db = Database::open_with_cadence(&path, None).await.unwrap();
Fixture {
db,
_dir: dir,
path,
}
}
fn concept(i: usize) -> ConceptUpsert {
ConceptUpsert::new(format!("c{i:07}"), format!("Concept {i}"))
.content(format!("body text for concept number {i}"))
.valid_from(TS)
}
async fn seed_concepts(db: &Database, n: usize) {
for chunk in (0..n).collect::<Vec<_>>().chunks(2_000) {
db.write_concepts(chunk.iter().map(|i| concept(*i)).collect())
.await
.unwrap();
}
}
async fn seed_edges(db: &Database, edges: usize) {
for chunk in fixtures::Shape::StarOfStars.edges(edges + 1).chunks(2_000) {
db.bulk_import(chunk.to_vec()).await.unwrap();
}
}
fn write_path(c: &mut Criterion) {
let rt = runtime();
let fx = rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, 2_000 * scale()).await;
fx
});
let mut group = controlled_group(c, "write_path");
group.sample_size(50);
let db = &fx.db;
let counter = std::cell::Cell::new(0usize);
group.bench_function("assert_edge (§9 ≤ 5 ms)", |b| {
b.to_async(&rt).iter(|| {
let i = counter.get();
counter.set(i + 1);
async move {
db.assert_edge(
EdgeAssertion::new("c0000000", "c0000001", format!("B{i}"))
.valid_from(TS)
.valid_to(OPEN),
)
.await
.unwrap()
}
})
});
let ucount = std::cell::Cell::new(0usize);
group.bench_function("upsert_concept (§9 ≤ 3 ms)", |b| {
b.to_async(&rt).iter(|| {
let i = ucount.get();
ucount.set(i + 1);
async move {
db.upsert_concept(
ConceptUpsert::new("c0000000", format!("Rename {i}")).valid_from(TS),
)
.await
.unwrap()
}
})
});
group.finish();
let mut group = controlled_group(c, "chunk_commit");
group.sample_size(10);
group.bench_function("500_rows_trigger_amplified (§9 ≤ 3 ms)", |b| {
b.iter_batched(
|| {
rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, 501).await;
fx
})
},
|fx| {
let edges: Vec<EdgeAssertion> = (0..500)
.map(|k| {
EdgeAssertion::new("c0000000", format!("c{:07}", k + 1), "CHUNK")
.valid_from(TS)
.valid_to(OPEN)
})
.collect();
rt.block_on(fx.db.write_bulk_atomic(edges)).unwrap()
},
BatchSize::PerIteration,
)
});
group.finish();
let mut group = controlled_group(c, "chunk_commit_diagnostic");
group.sample_size(10);
group.bench_function("500_rows_no_triggers (trigger cost isolation)", |b| {
b.iter_batched(
|| {
rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, 501).await;
let raw = libsql::Builder::new_local(&fx.path).build().await.unwrap();
let conn = raw.connect().unwrap();
for t in ["trg_links_log_insert", "trg_links_current_sync"] {
conn.execute(&format!("DROP TRIGGER IF EXISTS {t}"), ())
.await
.unwrap();
}
(fx, raw, conn)
})
},
|(fx, _raw, conn)| {
rt.block_on(async {
let tx = conn
.transaction_with_behavior(libsql::TransactionBehavior::Immediate)
.await
.unwrap();
let stmt = tx.prepare(INSERT_LINK_SQL).await.unwrap();
for k in 0..500 {
stmt.reset();
stmt.execute(libsql::params![
"c0000000",
format!("c{:07}", k + 1),
"CHUNK",
TS,
OPEN,
1.0f64,
"{}",
TS
])
.await
.unwrap();
}
drop(stmt);
tx.commit().await.unwrap();
});
fx
},
BatchSize::PerIteration,
)
});
group.finish();
}
const INSERT_LINK_SQL: &str = "INSERT INTO links \
(source_id, target_id, edge_type, valid_from, valid_to, weight, properties, recorded_at) \
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)";
fn chunk_budget(c: &mut Criterion) {
let rt = runtime();
let mut group = controlled_group(c, "chunk_budget");
group.sample_size(20);
group.bench_function(
format!("edges/{} (§5.1.5 ≤ 3 ms)", chunk_rows::EDGES),
|b| {
b.iter_batched(
|| {
rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, chunk_rows::EDGES + 1).await;
fx
})
},
|fx| {
let edges: Vec<EdgeAssertion> = (0..chunk_rows::EDGES)
.map(|k| {
EdgeAssertion::new("c0000000", format!("c{:07}", k + 1), "CHUNK")
.valid_from(TS)
.valid_to(OPEN)
})
.collect();
rt.block_on(fx.db.write_bulk_atomic(edges)).unwrap()
},
BatchSize::PerIteration,
)
},
);
group.bench_function(
format!("concepts/{} (§5.1.5 ≤ 3 ms)", chunk_rows::CONCEPTS),
|b| {
b.iter_batched(
|| {
rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, chunk_rows::CONCEPTS).await;
fx
})
},
|fx| {
let rows: Vec<ConceptUpsert> = (0..chunk_rows::CONCEPTS)
.map(|i| {
ConceptUpsert::new(format!("c{i:07}"), format!("Rewritten {i}"))
.content(format!("new body for {i}"))
.valid_from(TS)
})
.collect();
rt.block_on(fx.db.write_concepts(rows)).unwrap()
},
BatchSize::PerIteration,
)
},
);
group.bench_function(
format!("annotations/{} (§5.1.5 ≤ 3 ms)", chunk_rows::ANNOTATIONS),
|b| {
b.iter_batched(
|| {
rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, chunk_rows::ANNOTATIONS).await;
fx
})
},
|fx| {
let rows: Vec<Annotation> = (0..chunk_rows::ANNOTATIONS)
.map(|i| Annotation {
concept_id: format!("c{i:07}"),
label: "community".into(),
value: format!("{}", i % 7),
})
.collect();
rt.block_on(fx.db.write_analytics_annotations(rows))
.unwrap()
},
BatchSize::PerIteration,
)
},
);
group.bench_function(
format!("embeddings/{} (§5.1.5 ≤ 3 ms)", chunk_rows::EMBEDDINGS),
|b| {
b.iter_batched(
|| {
rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, chunk_rows::EMBEDDINGS).await;
let model = ModelName::new("bench_v1").unwrap();
fx.db.register_model(&model, 8).await.unwrap();
(fx, model)
})
},
|(fx, model)| {
let rows: Vec<(String, Vec<f32>)> = (0..chunk_rows::EMBEDDINGS)
.map(|i| {
let t = i as f32 / 500.0;
(
format!("c{i:07}"),
(0..8).map(|k| ((t + k as f32) * 0.37).sin()).collect(),
)
})
.collect();
rt.block_on(fx.db.upsert_embeddings(&model, rows)).unwrap()
},
BatchSize::PerIteration,
)
},
);
group.finish();
}
fn chunk_scaling(c: &mut Criterion) {
let rt = runtime();
const SIZES: [usize; 6] = [1, 10, 50, 100, 500, 1_000];
let mut group = controlled_group(c, "chunk_scaling");
group.sample_size(10);
for n in SIZES {
group.bench_with_input(BenchmarkId::new("edges", n), &n, |b, &n| {
b.iter_batched(
|| {
rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, n + 1).await;
fx
})
},
|fx| {
let edges: Vec<EdgeAssertion> = (0..n)
.map(|k| {
EdgeAssertion::new("c0000000", format!("c{:07}", k + 1), "CHUNK")
.valid_from(TS)
.valid_to(OPEN)
})
.collect();
rt.block_on(fx.db.write_bulk_atomic(edges)).unwrap()
},
BatchSize::PerIteration,
)
});
group.bench_with_input(BenchmarkId::new("concepts", n), &n, |b, &n| {
b.iter_batched(
|| {
rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, n).await;
fx
})
},
|fx| {
let rows: Vec<ConceptUpsert> = (0..n)
.map(|i| {
ConceptUpsert::new(format!("c{i:07}"), format!("Rewritten {i}"))
.content(format!("new body for {i}"))
.valid_from(TS)
})
.collect();
rt.block_on(fx.db.write_concepts(rows)).unwrap()
},
BatchSize::PerIteration,
)
});
group.bench_with_input(BenchmarkId::new("annotations", n), &n, |b, &n| {
b.iter_batched(
|| {
rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, n).await;
fx
})
},
|fx| {
let rows: Vec<Annotation> = (0..n)
.map(|i| Annotation {
concept_id: format!("c{i:07}"),
label: "community".into(),
value: format!("{}", i % 7),
})
.collect();
rt.block_on(fx.db.write_analytics_annotations(rows))
.unwrap()
},
BatchSize::PerIteration,
)
});
group.bench_with_input(BenchmarkId::new("embeddings", n), &n, |b, &n| {
b.iter_batched(
|| {
rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, n).await;
let model = ModelName::new("bench_v1").unwrap();
fx.db.register_model(&model, 8).await.unwrap();
(fx, model)
})
},
|(fx, model)| {
let rows: Vec<(String, Vec<f32>)> = (0..n)
.map(|i| {
let t = i as f32 / 500.0;
(
format!("c{i:07}"),
(0..8).map(|k| ((t + k as f32) * 0.37).sin()).collect(),
)
})
.collect();
rt.block_on(fx.db.upsert_embeddings(&model, rows)).unwrap()
},
BatchSize::PerIteration,
)
});
}
group.finish();
}
fn bulk_chunks(c: &mut Criterion) {
let rt = runtime();
let mut group = controlled_group(c, "bulk_chunks");
group.sample_size(10);
group.bench_function("concepts_500 (upsert + FTS triggers)", |b| {
b.iter_batched(
|| {
rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, 500).await;
fx
})
},
|fx| {
let rows: Vec<ConceptUpsert> = (0..500)
.map(|i| {
ConceptUpsert::new(format!("c{i:07}"), format!("Rewritten {i}"))
.content(format!("new body for {i}"))
.valid_from(TS)
})
.collect();
rt.block_on(fx.db.write_concepts(rows)).unwrap()
},
BatchSize::PerIteration,
)
});
group.bench_function("annotations_500 (no triggers — the control)", |b| {
b.iter_batched(
|| {
rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, 500).await;
fx
})
},
|fx| {
let rows: Vec<Annotation> = (0..500)
.map(|i| Annotation {
concept_id: format!("c{i:07}"),
label: "community".into(),
value: format!("{}", i % 7),
})
.collect();
rt.block_on(fx.db.write_analytics_annotations(rows))
.unwrap()
},
BatchSize::PerIteration,
)
});
group.bench_function("embeddings_500 (DiskANN maintenance)", |b| {
b.iter_batched(
|| {
rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, 500).await;
let model = ModelName::new("bench_v1").unwrap();
fx.db.register_model(&model, 8).await.unwrap();
(fx, model)
})
},
|(fx, model)| {
let rows: Vec<(String, Vec<f32>)> = (0..500)
.map(|i| {
let t = i as f32 / 500.0;
(
format!("c{i:07}"),
(0..8).map(|k| ((t + k as f32) * 0.37).sin()).collect(),
)
})
.collect();
rt.block_on(fx.db.upsert_embeddings(&model, rows)).unwrap()
},
BatchSize::PerIteration,
)
});
group.finish();
}
fn traversal(c: &mut Criterion) {
let rt = runtime();
let edges = 1_000 * scale();
let fx = rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, edges + 1).await;
seed_edges(&fx.db, edges).await;
fx
});
let mut group = controlled_group(c, "traversal");
group.sample_size(50);
group.bench_function("three_hop_warm (§9 ≤ 10 ms)", |b| {
b.to_async(&rt).iter(|| async {
TraversalBuilder::new("c0000000")
.max_depth(3)
.execute_ids(fx.db.read_conn(), TS)
.await
.unwrap()
})
});
group.bench_function("as_of_edges (§9 ≤ 15 ms)", |b| {
b.to_async(&rt)
.iter(|| async { query_as_of_edges(fx.db.read_conn(), TS).await.unwrap() })
});
group.finish();
}
fn replay(c: &mut Criterion) {
let rt = runtime();
let n = 5_000 * scale();
let (fx, now, snaps) = rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, n).await;
let now: String = fx
.db
.read_conn()
.query("SELECT MAX(recorded_at) FROM transaction_log", ())
.await
.unwrap()
.next()
.await
.unwrap()
.unwrap()
.get(0)
.unwrap();
let snaps = fx.path.parent().unwrap().join("bench_snaps");
let base = reconstruct(fx.db.read_conn(), &now, None, None)
.await
.unwrap();
save_snapshot(&snaps, &base).unwrap();
for i in n..n + 50 {
fx.db.upsert_concept(concept(i)).await.unwrap();
}
let now: String = fx
.db
.read_conn()
.query("SELECT MAX(recorded_at) FROM transaction_log", ())
.await
.unwrap()
.next()
.await
.unwrap()
.unwrap()
.get(0)
.unwrap();
(fx, now, snaps)
});
let mut group = controlled_group(c, "replay");
group.sample_size(20);
group.bench_function("reconstruct_full_fold (§9 ≤ 100 ms @ 10K)", |b| {
b.to_async(&rt).iter(|| async {
reconstruct(fx.db.read_conn(), &now, None, None)
.await
.unwrap()
})
});
group.bench_function("reconstruct_composed (§9 ≤ 200 ms @ 1M)", |b| {
b.to_async(&rt).iter(|| async {
reconstruct(fx.db.read_conn(), &now, None, Some(&snaps))
.await
.unwrap()
})
});
group.finish();
}
fn integrity(c: &mut Criterion) {
let rt = runtime();
let edges = 2_000 * scale();
let fx = rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, edges + 1).await;
seed_edges(&fx.db, edges).await;
fx
});
let mut group = controlled_group(c, "integrity");
group.sample_size(10);
group.bench_function("audit_current (§9 ≤ 200 ms @ 100K)", |b| {
b.to_async(&rt)
.iter(|| async { audit_current(fx.db.read_conn()).await.unwrap() })
});
group.bench_function("rebuild_current (§9 ≤ 500 ms @ 100K)", |b| {
b.to_async(&rt)
.iter(|| async { fx.db.rebuild_current().await.unwrap() })
});
group.finish();
}
fn search(c: &mut Criterion) {
let rt = runtime();
let n = 2_000 * scale();
let (fx, model) = rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, n).await;
let model = ModelName::new("bench_v1").unwrap();
fx.db.register_model(&model, 8).await.unwrap();
let rows: Vec<(String, Vec<f32>)> = (0..n)
.map(|i| {
let t = i as f32 / n as f32;
(
format!("c{i:07}"),
(0..8).map(|k| ((t + k as f32) * 0.37).sin()).collect(),
)
})
.collect();
fx.db.upsert_embeddings(&model, rows).await.unwrap();
(fx, model)
});
let query: Vec<f32> = (0..8).map(|k| ((k as f32) * 0.37).sin()).collect();
let mut group = controlled_group(c, "search");
group.sample_size(50);
group.bench_function("vector_top10 (§9 ≤ 20 ms @ 100K)", |b| {
b.to_async(&rt).iter(|| async {
search_vector(fx.db.read_conn(), &query, &model, 10)
.await
.unwrap()
})
});
group.bench_function("hybrid_top10 (§9 ≤ 50 ms @ 100K)", |b| {
b.to_async(&rt).iter(|| async {
HybridSearch::new(model.clone(), "body text concept", query.clone())
.top_k(10)
.execute(fx.db.read_conn())
.await
.unwrap()
})
});
group.finish();
}
fn snapshot(c: &mut Criterion) {
let rt = runtime();
let edges = 2_000 * scale();
let (fx, state) = rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, edges + 1).await;
seed_edges(&fx.db, edges).await;
let now: String = fx
.db
.read_conn()
.query("SELECT MAX(recorded_at) FROM transaction_log", ())
.await
.unwrap()
.next()
.await
.unwrap()
.unwrap()
.get(0)
.unwrap();
let state = reconstruct(fx.db.read_conn(), &now, None, None)
.await
.unwrap();
(fx, state)
});
let mut group = controlled_group(c, "snapshot");
group.sample_size(20);
group.bench_function("save_snapshot (§9 ≤ 2 s @ 100K edges)", |b| {
b.iter_batched(
|| tempfile::TempDir::new().unwrap(),
|dir| save_snapshot(dir.path(), &state).unwrap(),
BatchSize::SmallInput,
)
});
let _ = &fx;
group.finish();
}
fn graph_analytics(c: &mut Criterion) {
let rt = runtime();
let edges = 1_000 * scale();
let fx = rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, edges + 1).await;
seed_edges(&fx.db, edges).await;
fx
});
let budget = 64 << 20;
let graph = rt.block_on(async {
fx.db
.load_subgraph("c0000000", 3, TS, budget)
.await
.unwrap()
});
eprintln!(
"graph fixture: {} nodes, {} edges",
graph.nodes.len(),
graph.edge_count()
);
let mut group = controlled_group(c, "graph_analytics");
group.sample_size(20);
group.bench_function("load_subgraph_3hop", |b| {
b.to_async(&rt).iter(|| async {
fx.db
.load_subgraph("c0000000", 3, TS, budget)
.await
.unwrap()
})
});
group.bench_function("dijkstra", |b| b.iter(|| dijkstra(&graph, "c0000000")));
group.bench_function("astar", |b| {
b.iter(|| astar(&graph, "c0000000", "c0000001", |_, _| 0.0))
});
group.bench_function("scc", |b| b.iter(|| scc(&graph)));
group.bench_function("k_core", |b| b.iter(|| k_core(&graph, 2)));
group.bench_function("louvain", |b| b.iter(|| louvain(&graph)));
group.finish();
}
fn hydrate_scaling(c: &mut Criterion) {
let rt = runtime();
let fx = rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, 1_000).await;
fx
});
let mut group = controlled_group(c, "hydrate_scaling");
group.sample_size(30);
for n in [100usize, 400, 1_000] {
let ids: Vec<String> = (0..n).map(|i| format!("c{i:07}")).collect();
group.bench_with_input(BenchmarkId::from_parameter(n), &ids, |b, ids| {
b.to_async(&rt).iter(|| async {
hydrate_attributes(fx.db.read_conn(), ids, TS, AttributeMode::Current)
.await
.unwrap()
})
});
}
group.finish();
}
fn overlap_guard(c: &mut Criterion) {
let rt = runtime();
let hub = 2_000 * scale();
let mut group = controlled_group(c, "overlap_guard");
group.sample_size(20);
for degree in [0usize, hub] {
group.bench_with_input(
BenchmarkId::from_parameter(degree),
°ree,
|b, °ree| {
b.iter_batched(
|| {
rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, degree + 2).await;
if degree > 0 {
seed_edges(&fx.db, degree).await;
}
fx
})
},
|fx| {
rt.block_on(
fx.db.assert_edge(
EdgeAssertion::new("c0000000", "c0000001", "PROBED")
.valid_from(TS)
.valid_to("2027-01-01T00:00:00.000000Z"),
),
)
.unwrap()
},
BatchSize::PerIteration,
)
},
);
}
group.finish();
}
fn archive_cost(c: &mut Criterion) {
let rt = runtime();
let edges = 2_000 * scale();
let mut group = controlled_group(c, "archive");
group.sample_size(10);
group.bench_function("archive_superseded", |b| {
b.iter_batched(
|| {
rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, edges + 1).await;
let mut batch = Vec::with_capacity(edges);
for i in 1..=edges {
batch.push(
EdgeAssertion::new("c0000000", format!("c{i:07}"), "LINKS")
.valid_from(TS)
.valid_to("2026-06-01T00:00:00.000000Z"),
);
}
for chunk in batch.chunks(2_000) {
fx.db.bulk_import(chunk.to_vec()).await.unwrap();
}
fx
})
},
|fx| {
let report = rt
.block_on(fx.db.archive("2099-01-01T00:00:00.000000Z"))
.unwrap();
assert!(report.links_archived > 0, "the fixture archived nothing");
},
BatchSize::PerIteration,
)
});
group.finish();
}
fn filtered_vector(c: &mut Criterion) {
let rt = runtime();
let n = 2_000 * scale();
let (fx, model) = rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, n).await;
seed_edges(&fx.db, n.min(1_000)).await;
let model = ModelName::new("bench_v1").unwrap();
fx.db.register_model(&model, 8).await.unwrap();
let rows: Vec<(String, Vec<f32>)> = (0..n)
.map(|i| {
let t = i as f32 / n as f32;
(
format!("c{i:07}"),
(0..8).map(|k| ((t + k as f32) * 0.37).sin()).collect(),
)
})
.collect();
fx.db.upsert_embeddings(&model, rows).await.unwrap();
(fx, model)
});
let query: Vec<f32> = (0..8).map(|k| ((k as f32) * 0.37).sin()).collect();
let mut group = controlled_group(c, "filtered_vector");
group.sample_size(30);
group.bench_function("planner_input/corpus_size", |b| {
let sql = format!("SELECT COUNT(*) FROM {}", model.table());
b.to_async(&rt).iter(|| async {
let n: i64 = fx
.db
.read_conn()
.query(&sql, ())
.await
.unwrap()
.next()
.await
.unwrap()
.unwrap()
.get(0)
.unwrap();
n
})
});
group.bench_function("planner_input/declared_dimension", |b| {
b.to_async(&rt)
.iter(|| async { declared_dimension(fx.db.read_conn(), &model).await.unwrap() })
});
group.bench_function("filtered_top10", |b| {
b.to_async(&rt).iter(|| async {
FilteredVectorSearch::new(
model.clone(),
query.clone(),
TraversalBuilder::new("c0000000").max_depth(3),
)
.top_k(10)
.execute(fx.db.read_conn(), TS)
.await
.unwrap()
})
});
group.finish();
}
fn chunk_index_cost(c: &mut Criterion) {
let rt = runtime();
let mut group = controlled_group(c, "chunk_index_cost");
group.sample_size(20);
for (label, hub, with_index) in [
("empty/with_index", 0usize, true),
("empty/no_index", 0, false),
("hub2000/with_index", 2_000, true),
("hub2000/no_index", 2_000, false),
] {
group.bench_function(label, |b| {
b.iter_batched(
|| {
rt.block_on(async {
let fx = fixture().await;
seed_concepts(&fx.db, hub + chunk_rows::EDGES + 1).await;
if hub > 0 {
let batch: Vec<EdgeAssertion> = (1..=hub)
.map(|i| {
EdgeAssertion::new("c0000000", format!("c{i:07}"), "LINKS")
.valid_from(TS)
.valid_to(OPEN)
})
.collect();
for chunk in batch.chunks(2_000) {
fx.db.bulk_import(chunk.to_vec()).await.unwrap();
}
}
if !with_index {
fx.db
.raw()
.connect()
.unwrap()
.execute("DROP INDEX IF EXISTS idx_lc_open_interval", ())
.await
.unwrap();
}
fx
})
},
|fx| {
let base = hub + 1;
let edges: Vec<EdgeAssertion> = (0..chunk_rows::EDGES)
.map(|k| {
EdgeAssertion::new("c0000000", format!("c{:07}", base + k), "CHUNK")
.valid_from(TS)
.valid_to(OPEN)
})
.collect();
rt.block_on(fx.db.write_bulk_atomic(edges)).unwrap()
},
BatchSize::PerIteration,
)
});
}
group.finish();
}
fn fixture_matrix(c: &mut Criterion) {
use fixtures::{depth_to_cover, seed, ALL_SHAPES};
let rt = runtime();
let nodes = 600 * scale();
let budget = 512 << 20;
let mut group = controlled_group(c, "fixture_matrix");
group.sample_size(10);
for &shape in ALL_SHAPES {
let depth = depth_to_cover(shape, nodes, 0.9, nodes) as u32;
let start = shape.start_node(nodes);
let fx = rt.block_on(async {
let fx = fixture().await;
seed(&fx.db, shape, nodes).await;
fx
});
group.bench_with_input(
BenchmarkId::new("load_subgraph_90pct", shape.name()),
&depth,
|b, &depth| {
b.to_async(&rt).iter(|| async {
fx.db
.load_subgraph(&start, depth, TS, budget)
.await
.unwrap()
})
},
);
}
group.finish();
}
criterion_group!(
budgets,
write_path,
bulk_chunks,
chunk_budget,
chunk_scaling,
traversal,
replay,
integrity,
search,
snapshot,
graph_analytics,
hydrate_scaling,
overlap_guard,
archive_cost,
filtered_vector,
chunk_index_cost,
fixture_matrix
);
criterion_main!(budgets);