graph_api_benches/index/no_index/
mod.rs

1use criterion::{BenchmarkGroup, Throughput, measurement::WallTime};
2use graph_api_derive::{EdgeExt, VertexExt};
3#[cfg(feature = "element-removal")]
4use graph_api_lib::SupportsElementRemoval;
5use graph_api_lib::{Graph, VertexSearch};
6use std::fmt::Debug;
7use uuid::Uuid;
8
9// Define a model with no indexes for baseline performance
10#[derive(Debug, Clone, VertexExt)]
11pub enum Vertex {
12    Person {
13        name: String,
14        age: u64,
15        unique_id: Uuid,
16        username: String,
17        biography: String,
18    },
19    Project {
20        name: String,
21    },
22    Rust,
23}
24
25#[derive(Debug, Clone, EdgeExt)]
26pub enum Edge {
27    Knows { since: i32 },
28    Created,
29    Language { name: String },
30}
31
32// Generate test data with the NoIndexVertex and NoIndexEdge models
33pub fn generate_test_data<G>(graph: &mut G) -> (G::VertexId, G::VertexId)
34where
35    G: Graph<Vertex = Vertex, Edge = Edge>,
36{
37    let src = graph.add_vertex(Vertex::Person {
38        name: "Source".to_string(),
39        age: 30,
40        unique_id: Uuid::new_v4(),
41        username: "source_user".to_string(),
42        biography: "Source vertex".to_string(),
43    });
44
45    let dst = graph.add_vertex(Vertex::Person {
46        name: "Target".to_string(),
47        age: 35,
48        unique_id: Uuid::new_v4(),
49        username: "target_user".to_string(),
50        biography: "Target vertex".to_string(),
51    });
52
53    (src, dst)
54}
55
56// Individual benchmark functions
57
58pub fn bench_vertex_insertion<G>(
59    group: &mut BenchmarkGroup<WallTime>,
60    setup: impl Fn() -> G + Clone,
61) where
62    G: Graph<Vertex = Vertex, Edge = Edge>,
63{
64    // Benchmark vertex insertion without any indexes
65    group.throughput(Throughput::Elements(1));
66    group.bench_function("vertex_insertion_no_index", |b| {
67        let mut counter = 0;
68        let mut graph = setup();
69        b.iter(|| {
70            counter += 1;
71            graph.add_vertex(Vertex::Person {
72                name: format!("Person{}", counter),
73                age: 30,
74                unique_id: Uuid::new_v4(),
75                username: format!("noindex_user{}", counter),
76                biography: "Test biography without index".to_string(),
77            });
78        })
79    });
80}
81
82pub fn bench_edge_insertion<G>(group: &mut BenchmarkGroup<WallTime>, setup: impl Fn() -> G + Clone)
83where
84    G: Graph<Vertex = Vertex, Edge = Edge>,
85{
86    // Benchmark edge insertion without indexes
87    group.bench_function("edge_insertion_no_index", |b| {
88        // Setup: Create graph with minimal data for adding edges
89        let mut graph = setup();
90        let (src, dst) = generate_test_data(&mut graph);
91
92        b.iter(|| graph.add_edge(src, dst, Edge::Knows { since: 2023 }))
93    });
94}
95
96pub fn bench_vertex_scan<G>(group: &mut BenchmarkGroup<WallTime>, setup: impl Fn() -> G + Clone)
97where
98    G: Graph<Vertex = Vertex, Edge = Edge>,
99{
100    // Benchmark vertex scan (the non-indexed operation)
101    group.bench_function("vertex_scan_no_index", |b| {
102        // Setup: Create graph with random data
103        let mut graph = setup();
104
105        // Add some vertices for scanning
106        for i in 0..100 {
107            graph.add_vertex(Vertex::Person {
108                name: format!("Person{}", i),
109                age: 25 + (i % 50) as u64,
110                unique_id: Uuid::new_v4(),
111                username: format!("user{}", i),
112                biography: format!("Bio for person {}", i),
113            });
114        }
115
116        b.iter(|| {
117            graph
118                .walk()
119                .vertices(VertexSearch::scan())
120                .take(10)
121                .collect::<Vec<_>>()
122        })
123    });
124}
125
126#[cfg(feature = "element-removal")]
127pub fn bench_vertex_removal<G>(group: &mut BenchmarkGroup<WallTime>, setup: impl Fn() -> G + Clone)
128where
129    G: Graph<Vertex = Vertex, Edge = Edge> + SupportsElementRemoval,
130{
131    // Benchmark vertex removal without indexes
132    group.bench_function("vertex_removal_no_index", |b| {
133        // Setup: Create a new graph for each iteration
134        b.iter_with_setup(
135            || {
136                let mut graph = setup();
137                let vertex_id = graph.add_vertex(Vertex::Person {
138                    name: "NoIndexRemoveMe".to_string(),
139                    age: 25,
140                    unique_id: Uuid::new_v4(),
141                    username: "noindex_remove_user".to_string(),
142                    biography: "To be removed without index".to_string(),
143                });
144                (graph, vertex_id)
145            },
146            |(mut graph, vertex_id)| {
147                graph.remove_vertex(vertex_id);
148            },
149        )
150    });
151}
152
153#[cfg(not(feature = "element-removal"))]
154pub fn bench_vertex_removal<G>(
155    _group: &mut BenchmarkGroup<WallTime>,
156    _setup: impl Fn() -> G + Clone,
157) where
158    G: Graph<Vertex = Vertex, Edge = Edge>,
159{
160    // No-op when feature is disabled
161}
162
163#[cfg(feature = "element-removal")]
164pub fn bench_edge_removal<G>(group: &mut BenchmarkGroup<WallTime>, setup: impl Fn() -> G + Clone)
165where
166    G: Graph<Vertex = Vertex, Edge = Edge> + SupportsElementRemoval,
167{
168    // Benchmark edge removal without indexes
169    group.bench_function("edge_removal_no_index", |b| {
170        // Setup: Create a new graph with an edge for each iteration
171        b.iter_with_setup(
172            || {
173                let mut graph = setup();
174                let (src, dst) = generate_test_data(&mut graph);
175                let edge_id = graph.add_edge(src, dst, Edge::Knows { since: 2020 });
176                (graph, edge_id)
177            },
178            |(mut graph, edge_id)| {
179                graph.remove_edge(edge_id);
180            },
181        )
182    });
183}
184
185#[cfg(not(feature = "element-removal"))]
186pub fn bench_edge_removal<G>(_group: &mut BenchmarkGroup<WallTime>, _setup: impl Fn() -> G + Clone)
187where
188    G: Graph<Vertex = Vertex, Edge = Edge>,
189{
190    // No-op when feature is disabled
191}