Skip to main content

benchmark/
benchmark.rs

1use tiny_varint::{VarintValue, varint, encode, decode};
2use std::time::{Instant, Duration};
3
4// Simple benchmark helper structure
5struct Benchmark {
6    name: &'static str,
7    iterations: usize,
8    total_time: Duration,
9}
10
11impl Benchmark {
12    fn new(name: &'static str, iterations: usize) -> Self {
13        Benchmark {
14            name,
15            iterations,
16            total_time: Duration::new(0, 0),
17        }
18    }
19    
20    fn run<F>(&mut self, mut func: F) where F: FnMut() {
21        // Warm up first
22        for _ in 0..10 {
23            func();
24        }
25        
26        // Actual timing
27        let start = Instant::now();
28        for _ in 0..self.iterations {
29            func();
30        }
31        self.total_time = start.elapsed();
32    }
33    
34    fn report(&self) {
35        let avg_time_ns = self.total_time.as_nanos() as f64 / self.iterations as f64;
36        println!("{}: {:.2} ns per operation ({} iterations in {:?})", 
37            self.name, avg_time_ns, self.iterations, self.total_time);
38    }
39}
40
41fn main() {
42    println!("VarintValue Performance Test");
43    println!("===========================\n");
44    
45    // Test parameters
46    const ITERATIONS: usize = 1_000_000;
47    
48    // Prepare test data and buffer
49    let test_values = [
50        varint!(u8: 127),
51        varint!(u16: 16383),
52        varint!(u32: 1000000),
53        varint!(i8: -42),
54        varint!(i16: -1000),
55        varint!(i32: -100000),
56        varint!(u64: 1_000_000_000_000),
57    ];
58    
59    let mut buffer = [0u8; 20];
60    
61    // 1. Test type ID calculation performance
62    let mut benchmark = Benchmark::new("Type ID calculation", ITERATIONS);
63    benchmark.run(|| {
64        for value in &test_values {
65            let _ = value.get_type_id();
66        }
67    });
68    benchmark.report();
69    
70    // 2. Test serialization size calculation performance
71    let mut benchmark = Benchmark::new("Serialization size calculation", ITERATIONS);
72    benchmark.run(|| {
73        for value in &test_values {
74            let _ = value.serialized_size();
75        }
76    });
77    benchmark.report();
78    
79    // 3. Test serialization performance
80    let mut benchmark = Benchmark::new("VarintValue serialization", ITERATIONS / 10);
81    benchmark.run(|| {
82        for value in &test_values {
83            let _ = value.to_bytes(&mut buffer);
84        }
85    });
86    benchmark.report();
87    
88    // Prepare deserialization test
89    let mut encoded_values = Vec::new();
90    let mut positions = Vec::new();
91    let mut pos = 0;
92    
93    for value in &test_values {
94        let bytes_written = value.to_bytes(&mut buffer[..]).unwrap();
95        encoded_values.extend_from_slice(&buffer[..bytes_written]);
96        positions.push((pos, bytes_written));
97        pos += bytes_written;
98    }
99    
100    // 4. Test deserialization performance
101    let mut benchmark = Benchmark::new("VarintValue deserialization", ITERATIONS / 10);
102    benchmark.run(|| {
103        for (start, len) in &positions {
104            let _ = VarintValue::from_bytes(&encoded_values[*start..*start + *len]);
105        }
106    });
107    benchmark.report();
108    
109    // 5. Compare with regular varint encoding (without type information)
110    let u32_values = [127u32, 16383, 1000000];
111    let mut benchmark = Benchmark::new("Regular u32 varint encoding", ITERATIONS);
112    benchmark.run(|| {
113        for value in &u32_values {
114            let _ = encode(*value, &mut buffer);
115        }
116    });
117    benchmark.report();
118    
119    // 6. Compare with regular varint decoding (without type information)
120    let mut u32_encoded = Vec::new();
121    let mut u32_positions = Vec::new();
122    let mut pos = 0;
123    
124    for value in &u32_values {
125        let bytes_written = encode(*value, &mut buffer).unwrap();
126        u32_encoded.extend_from_slice(&buffer[..bytes_written]);
127        u32_positions.push((pos, bytes_written));
128        pos += bytes_written;
129    }
130    
131    let mut benchmark = Benchmark::new("Regular u32 varint decoding", ITERATIONS);
132    benchmark.run(|| {
133        for (start, len) in &u32_positions {
134            let _ = decode::<u32>(&u32_encoded[*start..*start + *len]);
135        }
136    });
137    benchmark.report();
138    
139    println!("\nPerformance Summary:");
140    println!("1. VarintValue type information introduces some performance overhead");
141    println!("2. Optimizations (special zero handling, avoiding temporary buffers, etc.) effectively improve performance");
142    println!("3. For scenarios requiring mixed types, the performance cost is acceptable");
143}