1use tiny_varint::{VarintValue, varint, encode, decode};
2use std::time::{Instant, Duration};
3
4struct 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 for _ in 0..10 {
23 func();
24 }
25
26 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 const ITERATIONS: usize = 1_000_000;
47
48 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 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 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 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 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 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 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 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}