graph_api_benches/
edge.rs

1use crate::generators::generate_test_graph;
2
3use criterion::{BenchmarkGroup, Throughput, measurement::WallTime};
4#[cfg(feature = "element-removal")]
5use graph_api_lib::SupportsElementRemoval;
6use graph_api_lib::{EdgeReference, Graph};
7use graph_api_test::{Edge, Knows, Vertex};
8
9/// Run all edge operation benchmarks
10pub fn run_benchmarks<G: Graph<Vertex = Vertex, Edge = Edge>>(
11    group: &mut BenchmarkGroup<WallTime>,
12    setup: impl Fn() -> G + Clone,
13) {
14    bench_edge_add(group, setup.clone());
15    bench_edge_retrieve(group, setup.clone());
16    bench_edge_property_access(group, setup.clone());
17
18    // Only run removal benchmarks if the feature is enabled and graph supports removal
19    #[cfg(feature = "element-removal")]
20    run_removal_benchmarks(group, setup);
21}
22
23/// Run removal-specific benchmarks
24#[cfg(feature = "element-removal")]
25fn run_removal_benchmarks<G: Graph<Vertex = Vertex, Edge = Edge> + SupportsElementRemoval>(
26    group: &mut BenchmarkGroup<WallTime>,
27    setup: impl Fn() -> G + Clone,
28) {
29    bench_edge_remove(group, setup.clone());
30}
31
32/// Benchmark adding an edge
33fn bench_edge_add<G: Graph<Vertex = Vertex, Edge = Edge>>(
34    group: &mut BenchmarkGroup<WallTime>,
35    setup: impl Fn() -> G + Clone,
36) {
37    group.throughput(Throughput::Elements(1));
38    group.bench_function("edge_add", |b| {
39        b.iter_batched(
40            || {
41                // Setup: Create graph with test data
42                let mut graph = setup();
43                let refs = generate_test_graph(&mut graph);
44                (graph, refs.bryn, refs.julia)
45            },
46            |(mut graph, source, target)| {
47                graph.add_edge(source, target, Edge::Knows { since: 2023 })
48            },
49            criterion::BatchSize::SmallInput,
50        )
51    });
52}
53
54/// Benchmark retrieving an edge by ID
55fn bench_edge_retrieve<G: Graph<Vertex = Vertex, Edge = Edge>>(
56    group: &mut BenchmarkGroup<WallTime>,
57    setup: impl Fn() -> G + Clone,
58) {
59    group.throughput(Throughput::Elements(1));
60    group.bench_function("edge_retrieve", |b| {
61        // Setup: Create graph with test data
62        let mut graph = setup();
63        let refs = generate_test_graph(&mut graph);
64
65        b.iter(|| graph.edge(refs.bryn_knows_julia))
66    });
67}
68
69/// Benchmark removing an edge
70#[cfg(feature = "element-removal")]
71fn bench_edge_remove<G: Graph<Vertex = Vertex, Edge = Edge> + SupportsElementRemoval>(
72    group: &mut BenchmarkGroup<WallTime>,
73    setup: impl Fn() -> G + Clone,
74) {
75    group.throughput(Throughput::Elements(1));
76    group.bench_function("edge_remove", |b| {
77        b.iter_batched(
78            || {
79                // Setup: Create graph with random data
80                let mut graph = setup();
81                let refs = generate_test_graph(&mut graph);
82                // Add a new edge that we'll remove during the benchmark
83                let edge_id = graph.add_edge(refs.bryn, refs.julia, Edge::Knows { since: 2023 });
84                (graph, edge_id)
85            },
86            |(mut graph, edge_id)| graph.remove_edge(edge_id),
87            criterion::BatchSize::SmallInput,
88        )
89    });
90}
91
92/// Benchmark accessing edge properties
93fn bench_edge_property_access<G: Graph<Vertex = Vertex, Edge = Edge>>(
94    group: &mut BenchmarkGroup<WallTime>,
95    setup: impl Fn() -> G + Clone,
96) {
97    group.throughput(Throughput::Elements(1));
98    group.bench_function("edge_property_access", |b| {
99        // Setup: Create graph with test data
100        let mut graph = setup();
101        let refs = generate_test_graph(&mut graph);
102
103        b.iter(|| {
104            let edge = graph.edge(refs.bryn_knows_julia).unwrap();
105            let knows = edge.project::<Knows<_>>().expect("knows");
106            knows.since()
107        })
108    });
109}