benchmarking
This commit is contained in:
		
							
								
								
									
										336
									
								
								benches/bulk_ops.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										336
									
								
								benches/bulk_ops.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,336 @@ | ||||
| // benches/bulk_ops.rs | ||||
| use criterion::{criterion_group, criterion_main, Criterion, BenchmarkId, BatchSize}; | ||||
|  | ||||
| mod common; | ||||
| use common::*; | ||||
|  | ||||
| /// Benchmark bulk insert operations with varying batch sizes | ||||
| fn bench_bulk_insert(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("bulk_ops/insert"); | ||||
|      | ||||
|     for size in [100, 1_000, 10_000] { | ||||
|         for backend_type in BackendType::all() { | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/size", backend_type.name()), size), | ||||
|                 &(backend_type, size), | ||||
|                 |b, &(backend_type, size)| { | ||||
|                     b.iter_batched( | ||||
|                         || { | ||||
|                             let backend = BenchmarkBackend::new(backend_type).unwrap(); | ||||
|                             let mut generator = DataGenerator::new(42); | ||||
|                             let data = generator.generate_string_pairs(size, 100); | ||||
|                             (backend, data) | ||||
|                         }, | ||||
|                         |(backend, data)| { | ||||
|                             for (key, value) in data { | ||||
|                                 backend.storage.set(key, value).unwrap(); | ||||
|                             } | ||||
|                         }, | ||||
|                         BatchSize::SmallInput | ||||
|                     ); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| /// Benchmark bulk sequential read operations | ||||
| fn bench_bulk_read_sequential(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("bulk_ops/read_sequential"); | ||||
|      | ||||
|     for size in [1_000, 10_000] { | ||||
|         for backend_type in BackendType::all() { | ||||
|             let backend = setup_populated_backend(backend_type, size, 100) | ||||
|                 .expect("Failed to setup backend"); | ||||
|             let generator = DataGenerator::new(42); | ||||
|              | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/size", backend.name()), size), | ||||
|                 &(backend, size), | ||||
|                 |b, (backend, size)| { | ||||
|                     b.iter(|| { | ||||
|                         for i in 0..*size { | ||||
|                             let key = generator.generate_key("bench:key", i); | ||||
|                             backend.storage.get(&key).unwrap(); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| /// Benchmark bulk random read operations | ||||
| fn bench_bulk_read_random(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("bulk_ops/read_random"); | ||||
|      | ||||
|     for size in [1_000, 10_000] { | ||||
|         for backend_type in BackendType::all() { | ||||
|             let backend = setup_populated_backend(backend_type, size, 100) | ||||
|                 .expect("Failed to setup backend"); | ||||
|             let generator = DataGenerator::new(42); | ||||
|              | ||||
|             // Pre-generate random indices for fair comparison | ||||
|             let indices: Vec<usize> = (0..size) | ||||
|                 .map(|_| rand::random::<usize>() % size) | ||||
|                 .collect(); | ||||
|              | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/size", backend.name()), size), | ||||
|                 &(backend, indices), | ||||
|                 |b, (backend, indices)| { | ||||
|                     b.iter(|| { | ||||
|                         for &idx in indices { | ||||
|                             let key = generator.generate_key("bench:key", idx); | ||||
|                             backend.storage.get(&key).unwrap(); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| /// Benchmark bulk update operations | ||||
| fn bench_bulk_update(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("bulk_ops/update"); | ||||
|      | ||||
|     for size in [100, 1_000, 10_000] { | ||||
|         for backend_type in BackendType::all() { | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/size", backend_type.name()), size), | ||||
|                 &(backend_type, size), | ||||
|                 |b, &(backend_type, size)| { | ||||
|                     b.iter_batched( | ||||
|                         || { | ||||
|                             let backend = setup_populated_backend(backend_type, size, 100).unwrap(); | ||||
|                             let mut generator = DataGenerator::new(43); // Different seed for updates | ||||
|                             let updates = generator.generate_string_pairs(size, 100); | ||||
|                             (backend, updates) | ||||
|                         }, | ||||
|                         |(backend, updates)| { | ||||
|                             for (key, value) in updates { | ||||
|                                 backend.storage.set(key, value).unwrap(); | ||||
|                             } | ||||
|                         }, | ||||
|                         BatchSize::SmallInput | ||||
|                     ); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| /// Benchmark bulk delete operations | ||||
| fn bench_bulk_delete(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("bulk_ops/delete"); | ||||
|      | ||||
|     for size in [100, 1_000, 10_000] { | ||||
|         for backend_type in BackendType::all() { | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/size", backend_type.name()), size), | ||||
|                 &(backend_type, size), | ||||
|                 |b, &(backend_type, size)| { | ||||
|                     b.iter_batched( | ||||
|                         || { | ||||
|                             let backend = setup_populated_backend(backend_type, size, 100).unwrap(); | ||||
|                             let generator = DataGenerator::new(42); | ||||
|                             let keys: Vec<String> = (0..size) | ||||
|                                 .map(|i| generator.generate_key("bench:key", i)) | ||||
|                                 .collect(); | ||||
|                             (backend, keys) | ||||
|                         }, | ||||
|                         |(backend, keys)| { | ||||
|                             for key in keys { | ||||
|                                 backend.storage.del(key).unwrap(); | ||||
|                             } | ||||
|                         }, | ||||
|                         BatchSize::SmallInput | ||||
|                     ); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| /// Benchmark bulk hash insert operations | ||||
| fn bench_bulk_hash_insert(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("bulk_ops/hash_insert"); | ||||
|      | ||||
|     for size in [100, 1_000] { | ||||
|         for backend_type in BackendType::all() { | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/size", backend_type.name()), size), | ||||
|                 &(backend_type, size), | ||||
|                 |b, &(backend_type, size)| { | ||||
|                     b.iter_batched( | ||||
|                         || { | ||||
|                             let backend = BenchmarkBackend::new(backend_type).unwrap(); | ||||
|                             let mut generator = DataGenerator::new(42); | ||||
|                             let data = generator.generate_hash_data(size, 10, 100); | ||||
|                             (backend, data) | ||||
|                         }, | ||||
|                         |(backend, data)| { | ||||
|                             for (key, fields) in data { | ||||
|                                 backend.storage.hset(&key, fields).unwrap(); | ||||
|                             } | ||||
|                         }, | ||||
|                         BatchSize::SmallInput | ||||
|                     ); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| /// Benchmark bulk hash read operations (HGETALL) | ||||
| fn bench_bulk_hash_read(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("bulk_ops/hash_read"); | ||||
|      | ||||
|     for size in [100, 1_000] { | ||||
|         for backend_type in BackendType::all() { | ||||
|             let backend = setup_populated_backend_hashes(backend_type, size, 10, 100) | ||||
|                 .expect("Failed to setup backend"); | ||||
|             let generator = DataGenerator::new(42); | ||||
|              | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/size", backend.name()), size), | ||||
|                 &(backend, size), | ||||
|                 |b, (backend, size)| { | ||||
|                     b.iter(|| { | ||||
|                         for i in 0..*size { | ||||
|                             let key = generator.generate_key("bench:hash", i); | ||||
|                             backend.storage.hgetall(&key).unwrap(); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| /// Benchmark bulk list insert operations | ||||
| fn bench_bulk_list_insert(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("bulk_ops/list_insert"); | ||||
|      | ||||
|     for size in [100, 1_000] { | ||||
|         for backend_type in BackendType::all() { | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/size", backend_type.name()), size), | ||||
|                 &(backend_type, size), | ||||
|                 |b, &(backend_type, size)| { | ||||
|                     b.iter_batched( | ||||
|                         || { | ||||
|                             let backend = BenchmarkBackend::new(backend_type).unwrap(); | ||||
|                             let mut generator = DataGenerator::new(42); | ||||
|                             let data = generator.generate_list_data(size, 10, 100); | ||||
|                             (backend, data) | ||||
|                         }, | ||||
|                         |(backend, data)| { | ||||
|                             for (key, elements) in data { | ||||
|                                 backend.storage.rpush(&key, elements).unwrap(); | ||||
|                             } | ||||
|                         }, | ||||
|                         BatchSize::SmallInput | ||||
|                     ); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| /// Benchmark bulk list read operations (LRANGE) | ||||
| fn bench_bulk_list_read(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("bulk_ops/list_read"); | ||||
|      | ||||
|     for size in [100, 1_000] { | ||||
|         for backend_type in BackendType::all() { | ||||
|             let backend = setup_populated_backend_lists(backend_type, size, 10, 100) | ||||
|                 .expect("Failed to setup backend"); | ||||
|             let generator = DataGenerator::new(42); | ||||
|              | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/size", backend.name()), size), | ||||
|                 &(backend, size), | ||||
|                 |b, (backend, size)| { | ||||
|                     b.iter(|| { | ||||
|                         for i in 0..*size { | ||||
|                             let key = generator.generate_key("bench:list", i); | ||||
|                             backend.storage.lrange(&key, 0, -1).unwrap(); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| /// Benchmark mixed workload (70% reads, 30% writes) | ||||
| fn bench_mixed_workload(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("bulk_ops/mixed_workload"); | ||||
|      | ||||
|     for size in [1_000, 10_000] { | ||||
|         for backend_type in BackendType::all() { | ||||
|             let backend = setup_populated_backend(backend_type, size, 100) | ||||
|                 .expect("Failed to setup backend"); | ||||
|             let mut generator = DataGenerator::new(42); | ||||
|              | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/size", backend.name()), size), | ||||
|                 &(backend, size), | ||||
|                 |b, (backend, size)| { | ||||
|                     b.iter(|| { | ||||
|                         for i in 0..*size { | ||||
|                             if i % 10 < 7 { | ||||
|                                 // 70% reads | ||||
|                                 let key = generator.generate_key("bench:key", i % size); | ||||
|                                 backend.storage.get(&key).unwrap(); | ||||
|                             } else { | ||||
|                                 // 30% writes | ||||
|                                 let key = generator.generate_key("bench:key", i); | ||||
|                                 let value = generator.generate_value(100); | ||||
|                                 backend.storage.set(key, value).unwrap(); | ||||
|                             } | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| criterion_group!( | ||||
|     benches, | ||||
|     bench_bulk_insert, | ||||
|     bench_bulk_read_sequential, | ||||
|     bench_bulk_read_random, | ||||
|     bench_bulk_update, | ||||
|     bench_bulk_delete, | ||||
|     bench_bulk_hash_insert, | ||||
|     bench_bulk_hash_read, | ||||
|     bench_bulk_list_insert, | ||||
|     bench_bulk_list_read, | ||||
|     bench_mixed_workload, | ||||
| ); | ||||
|  | ||||
| criterion_main!(benches); | ||||
		Reference in New Issue
	
	Block a user