benchmarking

This commit is contained in:
Maxime Van Hees
2025-10-30 11:17:26 +01:00
parent 592b6c1ea9
commit 9136e5f3c0
16 changed files with 3611 additions and 0 deletions

View File

@@ -0,0 +1,131 @@
// benches/common/data_generator.rs
use rand::{Rng, SeedableRng};
use rand::rngs::StdRng;
/// Deterministic data generator for benchmarks
pub struct DataGenerator {
rng: StdRng,
}
impl DataGenerator {
/// Create a new data generator with a fixed seed for reproducibility
pub fn new(seed: u64) -> Self {
Self {
rng: StdRng::seed_from_u64(seed),
}
}
/// Generate a single key with the given prefix and ID
pub fn generate_key(&self, prefix: &str, id: usize) -> String {
format!("{}:{:08}", prefix, id)
}
/// Generate a random string value of the specified size
pub fn generate_value(&mut self, size: usize) -> String {
const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
(0..size)
.map(|_| {
let idx = self.rng.gen_range(0..CHARSET.len());
CHARSET[idx] as char
})
.collect()
}
/// Generate a batch of key-value pairs
pub fn generate_string_pairs(&mut self, count: usize, value_size: usize) -> Vec<(String, String)> {
(0..count)
.map(|i| {
let key = self.generate_key("bench:key", i);
let value = self.generate_value(value_size);
(key, value)
})
.collect()
}
/// Generate hash data (key -> field-value pairs)
pub fn generate_hash_data(&mut self, num_hashes: usize, fields_per_hash: usize, value_size: usize)
-> Vec<(String, Vec<(String, String)>)> {
(0..num_hashes)
.map(|i| {
let hash_key = self.generate_key("bench:hash", i);
let fields: Vec<(String, String)> = (0..fields_per_hash)
.map(|j| {
let field = format!("field{}", j);
let value = self.generate_value(value_size);
(field, value)
})
.collect();
(hash_key, fields)
})
.collect()
}
/// Generate list data (key -> list of elements)
pub fn generate_list_data(&mut self, num_lists: usize, elements_per_list: usize, element_size: usize)
-> Vec<(String, Vec<String>)> {
(0..num_lists)
.map(|i| {
let list_key = self.generate_key("bench:list", i);
let elements: Vec<String> = (0..elements_per_list)
.map(|_| self.generate_value(element_size))
.collect();
(list_key, elements)
})
.collect()
}
/// Generate keys for pattern matching tests
pub fn generate_pattern_keys(&mut self, count: usize) -> Vec<String> {
let mut keys = Vec::new();
// Generate keys with different patterns
for i in 0..count / 3 {
keys.push(format!("user:{}:profile", i));
}
for i in 0..count / 3 {
keys.push(format!("session:{}:data", i));
}
for i in 0..count / 3 {
keys.push(format!("cache:{}:value", i));
}
keys
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_deterministic_generation() {
let mut generator1 = DataGenerator::new(42);
let mut generator2 = DataGenerator::new(42);
let pairs1 = generator1.generate_string_pairs(10, 50);
let pairs2 = generator2.generate_string_pairs(10, 50);
assert_eq!(pairs1, pairs2, "Same seed should produce same data");
}
#[test]
fn test_value_size() {
let mut generator = DataGenerator::new(42);
let value = generator.generate_value(100);
assert_eq!(value.len(), 100);
}
#[test]
fn test_hash_generation() {
let mut generator = DataGenerator::new(42);
let hashes = generator.generate_hash_data(5, 10, 50);
assert_eq!(hashes.len(), 5);
for (_, fields) in hashes {
assert_eq!(fields.len(), 10);
for (_, value) in fields {
assert_eq!(value.len(), 50);
}
}
}
}