xref: /aosp_15_r20/external/cronet/third_party/rust/chromium_crates_io/vendor/prost-0.12.3/benches/varint.rs (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 use std::mem;
2 
3 use bytes::Buf;
4 use criterion::{Criterion, Throughput};
5 use prost::encoding::{decode_varint, encode_varint, encoded_len_varint};
6 use rand::{rngs::StdRng, seq::SliceRandom, SeedableRng};
7 
benchmark_varint(criterion: &mut Criterion, name: &str, mut values: Vec<u64>)8 fn benchmark_varint(criterion: &mut Criterion, name: &str, mut values: Vec<u64>) {
9     // Shuffle the values in a stable order.
10     values.shuffle(&mut StdRng::seed_from_u64(0));
11     let name = format!("varint/{}", name);
12 
13     let encoded_len = values
14         .iter()
15         .cloned()
16         .map(encoded_len_varint)
17         .sum::<usize>() as u64;
18     let decoded_len = (values.len() * mem::size_of::<u64>()) as u64;
19 
20     criterion
21         .benchmark_group(&name)
22         .bench_function("encode", {
23             let encode_values = values.clone();
24             move |b| {
25                 let mut buf = Vec::<u8>::with_capacity(encode_values.len() * 10);
26                 b.iter(|| {
27                     buf.clear();
28                     for &value in &encode_values {
29                         encode_varint(value, &mut buf);
30                     }
31                     criterion::black_box(&buf);
32                 })
33             }
34         })
35         .throughput(Throughput::Bytes(encoded_len));
36 
37     criterion
38         .benchmark_group(&name)
39         .bench_function("decode", {
40             let decode_values = values.clone();
41 
42             move |b| {
43                 let mut buf = Vec::with_capacity(decode_values.len() * 10);
44                 for &value in &decode_values {
45                     encode_varint(value, &mut buf);
46                 }
47 
48                 b.iter(|| {
49                     let mut buf = &mut buf.as_slice();
50                     while buf.has_remaining() {
51                         let result = decode_varint(&mut buf);
52                         debug_assert!(result.is_ok());
53                         criterion::black_box(&result);
54                     }
55                 })
56             }
57         })
58         .throughput(Throughput::Bytes(decoded_len));
59 
60     criterion
61         .benchmark_group(&name)
62         .bench_function("encoded_len", move |b| {
63             b.iter(|| {
64                 let mut sum = 0;
65                 for &value in &values {
66                     sum += encoded_len_varint(value);
67                 }
68                 criterion::black_box(sum);
69             })
70         })
71         .throughput(Throughput::Bytes(decoded_len));
72 }
73 
main()74 fn main() {
75     let mut criterion = Criterion::default().configure_from_args();
76 
77     // Benchmark encoding and decoding 100 small (1 byte) varints.
78     benchmark_varint(&mut criterion, "small", (0..100).collect());
79 
80     // Benchmark encoding and decoding 100 medium (5 byte) varints.
81     benchmark_varint(&mut criterion, "medium", (1 << 28..).take(100).collect());
82 
83     // Benchmark encoding and decoding 100 large (10 byte) varints.
84     benchmark_varint(&mut criterion, "large", (1 << 63..).take(100).collect());
85 
86     // Benchmark encoding and decoding 100 varints of mixed width (average 5.5 bytes).
87     benchmark_varint(
88         &mut criterion,
89         "mixed",
90         (0..10)
91             .flat_map(move |width| {
92                 let exponent = width * 7;
93                 (0..10).map(move |offset| offset + (1 << exponent))
94             })
95             .collect(),
96     );
97 
98     criterion.final_summary();
99 }
100