benchmarking
This commit is contained in:
		
							
								
								
									
										339
									
								
								benches/scan_ops.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										339
									
								
								benches/scan_ops.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,339 @@ | ||||
| // benches/scan_ops.rs | ||||
| use criterion::{criterion_group, criterion_main, Criterion, BenchmarkId}; | ||||
|  | ||||
| mod common; | ||||
| use common::*; | ||||
|  | ||||
| /// Benchmark SCAN operation - full database scan | ||||
| fn bench_scan_full(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("scan_ops/scan_full"); | ||||
|      | ||||
|     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"); | ||||
|              | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/size", backend.name()), size), | ||||
|                 &backend, | ||||
|                 |b, backend| { | ||||
|                     b.iter(|| { | ||||
|                         let mut cursor = 0u64; | ||||
|                         let mut total = 0; | ||||
|                         loop { | ||||
|                             let (next_cursor, items) = backend.storage | ||||
|                                 .scan(cursor, None, Some(100)) | ||||
|                                 .unwrap(); | ||||
|                             total += items.len(); | ||||
|                             if next_cursor == 0 { | ||||
|                                 break; | ||||
|                             } | ||||
|                             cursor = next_cursor; | ||||
|                         } | ||||
|                         total | ||||
|                     }); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| /// Benchmark SCAN operation with pattern matching | ||||
| fn bench_scan_pattern(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("scan_ops/scan_pattern"); | ||||
|      | ||||
|     for backend_type in BackendType::all() { | ||||
|         // Create backend with mixed key patterns | ||||
|         let backend = BenchmarkBackend::new(backend_type).expect("Failed to create backend"); | ||||
|         let mut generator = DataGenerator::new(42); | ||||
|          | ||||
|         // Insert keys with different patterns | ||||
|         for i in 0..3_000 { | ||||
|             let key = if i < 1_000 { | ||||
|                 format!("user:{}:profile", i) | ||||
|             } else if i < 2_000 { | ||||
|                 format!("session:{}:data", i - 1_000) | ||||
|             } else { | ||||
|                 format!("cache:{}:value", i - 2_000) | ||||
|             }; | ||||
|             let value = generator.generate_value(100); | ||||
|             backend.storage.set(key, value).unwrap(); | ||||
|         } | ||||
|          | ||||
|         // Benchmark pattern matching | ||||
|         for pattern in ["user:*", "session:*", "cache:*"] { | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/pattern", backend.name()), pattern), | ||||
|                 &(backend.storage.clone(), pattern), | ||||
|                 |b, (storage, pattern)| { | ||||
|                     b.iter(|| { | ||||
|                         let mut cursor = 0u64; | ||||
|                         let mut total = 0; | ||||
|                         loop { | ||||
|                             let (next_cursor, items) = storage | ||||
|                                 .scan(cursor, Some(pattern), Some(100)) | ||||
|                                 .unwrap(); | ||||
|                             total += items.len(); | ||||
|                             if next_cursor == 0 { | ||||
|                                 break; | ||||
|                             } | ||||
|                             cursor = next_cursor; | ||||
|                         } | ||||
|                         total | ||||
|                     }); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| /// Benchmark HSCAN operation - scan hash fields | ||||
| fn bench_hscan(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("scan_ops/hscan"); | ||||
|      | ||||
|     for fields_count in [10, 100] { | ||||
|         for backend_type in BackendType::all() { | ||||
|             let backend = setup_populated_backend_hashes(backend_type, 100, fields_count, 100) | ||||
|                 .expect("Failed to setup backend"); | ||||
|             let generator = DataGenerator::new(42); | ||||
|             let key = generator.generate_key("bench:hash", 0); | ||||
|              | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/fields", backend.name()), fields_count), | ||||
|                 &(backend, key), | ||||
|                 |b, (backend, key)| { | ||||
|                     b.iter(|| { | ||||
|                         let mut cursor = 0u64; | ||||
|                         let mut total = 0; | ||||
|                         loop { | ||||
|                             let (next_cursor, items) = backend.storage | ||||
|                                 .hscan(key, cursor, None, Some(10)) | ||||
|                                 .unwrap(); | ||||
|                             total += items.len(); | ||||
|                             if next_cursor == 0 { | ||||
|                                 break; | ||||
|                             } | ||||
|                             cursor = next_cursor; | ||||
|                         } | ||||
|                         total | ||||
|                     }); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| /// Benchmark HSCAN with pattern matching | ||||
| fn bench_hscan_pattern(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("scan_ops/hscan_pattern"); | ||||
|      | ||||
|     for backend_type in BackendType::all() { | ||||
|         let backend = BenchmarkBackend::new(backend_type).expect("Failed to create backend"); | ||||
|         let mut generator = DataGenerator::new(42); | ||||
|          | ||||
|         // Create a hash with mixed field patterns | ||||
|         let key = "bench:hash:0".to_string(); | ||||
|         let mut fields = Vec::new(); | ||||
|         for i in 0..100 { | ||||
|             let field = if i < 33 { | ||||
|                 format!("user_{}", i) | ||||
|             } else if i < 66 { | ||||
|                 format!("session_{}", i - 33) | ||||
|             } else { | ||||
|                 format!("cache_{}", i - 66) | ||||
|             }; | ||||
|             let value = generator.generate_value(100); | ||||
|             fields.push((field, value)); | ||||
|         } | ||||
|         backend.storage.hset(&key, fields).unwrap(); | ||||
|          | ||||
|         // Benchmark pattern matching | ||||
|         for pattern in ["user_*", "session_*", "cache_*"] { | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/pattern", backend.name()), pattern), | ||||
|                 &(backend.storage.clone(), key.clone(), pattern), | ||||
|                 |b, (storage, key, pattern)| { | ||||
|                     b.iter(|| { | ||||
|                         let mut cursor = 0u64; | ||||
|                         let mut total = 0; | ||||
|                         loop { | ||||
|                             let (next_cursor, items) = storage | ||||
|                                 .hscan(key, cursor, Some(pattern), Some(10)) | ||||
|                                 .unwrap(); | ||||
|                             total += items.len(); | ||||
|                             if next_cursor == 0 { | ||||
|                                 break; | ||||
|                             } | ||||
|                             cursor = next_cursor; | ||||
|                         } | ||||
|                         total | ||||
|                     }); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| /// Benchmark KEYS operation with various patterns | ||||
| fn bench_keys_operation(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("scan_ops/keys"); | ||||
|      | ||||
|     for backend_type in BackendType::all() { | ||||
|         // Create backend with mixed key patterns | ||||
|         let backend = BenchmarkBackend::new(backend_type).expect("Failed to create backend"); | ||||
|         let mut generator = DataGenerator::new(42); | ||||
|          | ||||
|         // Insert keys with different patterns | ||||
|         for i in 0..3_000 { | ||||
|             let key = if i < 1_000 { | ||||
|                 format!("user:{}:profile", i) | ||||
|             } else if i < 2_000 { | ||||
|                 format!("session:{}:data", i - 1_000) | ||||
|             } else { | ||||
|                 format!("cache:{}:value", i - 2_000) | ||||
|             }; | ||||
|             let value = generator.generate_value(100); | ||||
|             backend.storage.set(key, value).unwrap(); | ||||
|         } | ||||
|          | ||||
|         // Benchmark different patterns | ||||
|         for pattern in ["*", "user:*", "session:*", "*:profile", "user:*:profile"] { | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/pattern", backend.name()), pattern), | ||||
|                 &(backend.storage.clone(), pattern), | ||||
|                 |b, (storage, pattern)| { | ||||
|                     b.iter(|| { | ||||
|                         storage.keys(pattern).unwrap() | ||||
|                     }); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| /// Benchmark DBSIZE operation | ||||
| fn bench_dbsize(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("scan_ops/dbsize"); | ||||
|      | ||||
|     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"); | ||||
|              | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/size", backend.name()), size), | ||||
|                 &backend, | ||||
|                 |b, backend| { | ||||
|                     b.iter(|| { | ||||
|                         backend.storage.dbsize().unwrap() | ||||
|                     }); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| /// Benchmark LRANGE with different range sizes | ||||
| fn bench_lrange_sizes(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("scan_ops/lrange"); | ||||
|      | ||||
|     for range_size in [10, 50, 100] { | ||||
|         for backend_type in BackendType::all() { | ||||
|             let backend = setup_populated_backend_lists(backend_type, 100, 100, 100) | ||||
|                 .expect("Failed to setup backend"); | ||||
|             let generator = DataGenerator::new(42); | ||||
|             let key = generator.generate_key("bench:list", 0); | ||||
|              | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/range", backend.name()), range_size), | ||||
|                 &(backend, key, range_size), | ||||
|                 |b, (backend, key, range_size)| { | ||||
|                     b.iter(|| { | ||||
|                         backend.storage.lrange(key, 0, (*range_size - 1) as i64).unwrap() | ||||
|                     }); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| /// Benchmark HKEYS operation | ||||
| fn bench_hkeys(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("scan_ops/hkeys"); | ||||
|      | ||||
|     for fields_count in [10, 50, 100] { | ||||
|         for backend_type in BackendType::all() { | ||||
|             let backend = setup_populated_backend_hashes(backend_type, 100, fields_count, 100) | ||||
|                 .expect("Failed to setup backend"); | ||||
|             let generator = DataGenerator::new(42); | ||||
|             let key = generator.generate_key("bench:hash", 0); | ||||
|              | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/fields", backend.name()), fields_count), | ||||
|                 &(backend, key), | ||||
|                 |b, (backend, key)| { | ||||
|                     b.iter(|| { | ||||
|                         backend.storage.hkeys(key).unwrap() | ||||
|                     }); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| /// Benchmark HVALS operation | ||||
| fn bench_hvals(c: &mut Criterion) { | ||||
|     let mut group = c.benchmark_group("scan_ops/hvals"); | ||||
|      | ||||
|     for fields_count in [10, 50, 100] { | ||||
|         for backend_type in BackendType::all() { | ||||
|             let backend = setup_populated_backend_hashes(backend_type, 100, fields_count, 100) | ||||
|                 .expect("Failed to setup backend"); | ||||
|             let generator = DataGenerator::new(42); | ||||
|             let key = generator.generate_key("bench:hash", 0); | ||||
|              | ||||
|             group.bench_with_input( | ||||
|                 BenchmarkId::new(format!("{}/fields", backend.name()), fields_count), | ||||
|                 &(backend, key), | ||||
|                 |b, (backend, key)| { | ||||
|                     b.iter(|| { | ||||
|                         backend.storage.hvals(key).unwrap() | ||||
|                     }); | ||||
|                 } | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     group.finish(); | ||||
| } | ||||
|  | ||||
| criterion_group!( | ||||
|     benches, | ||||
|     bench_scan_full, | ||||
|     bench_scan_pattern, | ||||
|     bench_hscan, | ||||
|     bench_hscan_pattern, | ||||
|     bench_keys_operation, | ||||
|     bench_dbsize, | ||||
|     bench_lrange_sizes, | ||||
|     bench_hkeys, | ||||
|     bench_hvals, | ||||
| ); | ||||
|  | ||||
| criterion_main!(benches); | ||||
		Reference in New Issue
	
	Block a user