Rust · 5658 bytes Raw Blame History
1 use criterion::{black_box, criterion_group, criterion_main, Criterion, BenchmarkId, Throughput};
2 use std::time::Duration;
3 use tempfile::TempDir;
4 use tokio::runtime::Runtime;
5 use zephyrfs_cli::{Config, ZephyrClient};
6
7 fn config_benchmarks(c: &mut Criterion) {
8 let rt = Runtime::new().unwrap();
9
10 c.bench_function("config_default_creation", |b| {
11 b.iter(|| Config::default())
12 });
13
14 let temp_dir = tempfile::tempdir().unwrap();
15 let config = Config::default();
16 let config_path = temp_dir.path().join("bench_config.yaml");
17
18 // Benchmark config save
19 c.bench_function("config_save_yaml", |b| {
20 b.iter(|| {
21 config.save(Some(black_box(config_path.to_str().unwrap()))).unwrap();
22 })
23 });
24
25 // Ensure config file exists for load benchmark
26 config.save(Some(config_path.to_str().unwrap())).unwrap();
27
28 // Benchmark config load
29 c.bench_function("config_load_yaml", |b| {
30 b.iter(|| {
31 Config::load(Some(black_box(config_path.to_str().unwrap()))).unwrap();
32 })
33 });
34 }
35
36 fn file_operation_benchmarks(c: &mut Criterion) {
37 let rt = Runtime::new().unwrap();
38 let temp_dir = tempfile::tempdir().unwrap();
39
40 // Test different file sizes
41 let sizes = vec![1024, 10_240, 102_400, 1_048_576]; // 1KB, 10KB, 100KB, 1MB
42
43 for size in sizes {
44 let data = vec![0u8; size];
45 let file_path = temp_dir.path().join(format!("test_{}.bin", size));
46
47 c.bench_with_input(
48 BenchmarkId::new("file_write", size),
49 &(file_path.clone(), data.clone()),
50 |b, (path, data)| {
51 b.to_async(&rt).iter(|| async {
52 tokio::fs::write(black_box(path), black_box(data)).await.unwrap();
53 });
54 }
55 );
56
57 // Create file for read benchmark
58 rt.block_on(tokio::fs::write(&file_path, &data)).unwrap();
59
60 c.bench_with_input(
61 BenchmarkId::new("file_read", size),
62 &file_path,
63 |b, path| {
64 b.to_async(&rt).iter(|| async {
65 tokio::fs::read(black_box(path)).await.unwrap();
66 });
67 }
68 );
69 }
70 }
71
72 fn throughput_benchmarks(c: &mut Criterion) {
73 let mut group = c.benchmark_group("throughput");
74
75 // Config serialization throughput
76 let config = Config::default();
77
78 group.bench_function("yaml_serialization", |b| {
79 b.iter(|| {
80 serde_yaml::to_string(black_box(&config)).unwrap();
81 })
82 });
83
84 group.bench_function("json_serialization", |b| {
85 b.iter(|| {
86 serde_json::to_string(black_box(&config)).unwrap();
87 })
88 });
89
90 group.bench_function("toml_serialization", |b| {
91 b.iter(|| {
92 toml::to_string(black_box(&config)).unwrap();
93 })
94 });
95
96 // Deserialization benchmarks
97 let yaml_data = serde_yaml::to_string(&config).unwrap();
98 let json_data = serde_json::to_string(&config).unwrap();
99 let toml_data = toml::to_string(&config).unwrap();
100
101 group.bench_function("yaml_deserialization", |b| {
102 b.iter(|| {
103 serde_yaml::from_str::<Config>(black_box(&yaml_data)).unwrap();
104 })
105 });
106
107 group.bench_function("json_deserialization", |b| {
108 b.iter(|| {
109 serde_json::from_str::<Config>(black_box(&json_data)).unwrap();
110 })
111 });
112
113 group.bench_function("toml_deserialization", |b| {
114 b.iter(|| {
115 toml::from_str::<Config>(black_box(&toml_data)).unwrap();
116 })
117 });
118
119 group.finish();
120 }
121
122 fn client_benchmarks(c: &mut Criterion) {
123 let config = Config::default();
124
125 c.bench_function("client_creation", |b| {
126 b.iter(|| {
127 ZephyrClient::new(black_box(&config));
128 })
129 });
130 }
131
132 fn memory_benchmarks(c: &mut Criterion) {
133 let mut group = c.benchmark_group("memory");
134 group.measurement_time(Duration::from_secs(10));
135
136 // Benchmark memory usage for different operations
137 group.bench_function("config_clones", |b| {
138 let config = Config::default();
139 b.iter(|| {
140 let _clones: Vec<Config> = (0..1000).map(|_| config.clone()).collect();
141 })
142 });
143
144 group.bench_function("large_file_simulation", |b| {
145 b.iter(|| {
146 // Simulate processing a large file in chunks
147 let chunk_size = 1024 * 1024; // 1MB chunks
148 let num_chunks = 100;
149
150 for _ in 0..num_chunks {
151 let _chunk = vec![0u8; chunk_size];
152 black_box(_chunk);
153 }
154 })
155 });
156
157 group.finish();
158 }
159
160 fn hash_benchmarks(c: &mut Criterion) {
161 let mut group = c.benchmark_group("hashing");
162
163 let data_sizes = vec![1024, 10_240, 102_400, 1_048_576]; // 1KB to 1MB
164
165 for size in data_sizes {
166 let data = vec![0u8; size];
167
168 group.throughput(Throughput::Bytes(size as u64));
169
170 group.bench_with_input(
171 BenchmarkId::new("sha256", size),
172 &data,
173 |b, data| {
174 use sha2::{Sha256, Digest};
175 b.iter(|| {
176 let mut hasher = Sha256::new();
177 hasher.update(black_box(data));
178 hasher.finalize();
179 })
180 }
181 );
182 }
183
184 group.finish();
185 }
186
187 criterion_group!(
188 benches,
189 config_benchmarks,
190 file_operation_benchmarks,
191 throughput_benchmarks,
192 client_benchmarks,
193 memory_benchmarks,
194 hash_benchmarks
195 );
196 criterion_main!(benches);