summaryrefslogtreecommitdiffstats
path: root/third_party/rust/prost/benches/varint.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/prost/benches/varint.rs')
-rw-r--r--third_party/rust/prost/benches/varint.rs99
1 files changed, 99 insertions, 0 deletions
diff --git a/third_party/rust/prost/benches/varint.rs b/third_party/rust/prost/benches/varint.rs
new file mode 100644
index 0000000000..34951f5eaf
--- /dev/null
+++ b/third_party/rust/prost/benches/varint.rs
@@ -0,0 +1,99 @@
+use std::mem;
+
+use bytes::Buf;
+use criterion::{Criterion, Throughput};
+use prost::encoding::{decode_varint, encode_varint, encoded_len_varint};
+use rand::{rngs::StdRng, seq::SliceRandom, SeedableRng};
+
+fn benchmark_varint(criterion: &mut Criterion, name: &str, mut values: Vec<u64>) {
+ // Shuffle the values in a stable order.
+ values.shuffle(&mut StdRng::seed_from_u64(0));
+ let name = format!("varint/{}", name);
+
+ let encoded_len = values
+ .iter()
+ .cloned()
+ .map(encoded_len_varint)
+ .sum::<usize>() as u64;
+ let decoded_len = (values.len() * mem::size_of::<u64>()) as u64;
+
+ criterion
+ .benchmark_group(&name)
+ .bench_function("encode", {
+ let encode_values = values.clone();
+ move |b| {
+ let mut buf = Vec::<u8>::with_capacity(encode_values.len() * 10);
+ b.iter(|| {
+ buf.clear();
+ for &value in &encode_values {
+ encode_varint(value, &mut buf);
+ }
+ criterion::black_box(&buf);
+ })
+ }
+ })
+ .throughput(Throughput::Bytes(encoded_len));
+
+ criterion
+ .benchmark_group(&name)
+ .bench_function("decode", {
+ let decode_values = values.clone();
+
+ move |b| {
+ let mut buf = Vec::with_capacity(decode_values.len() * 10);
+ for &value in &decode_values {
+ encode_varint(value, &mut buf);
+ }
+
+ b.iter(|| {
+ let mut buf = &mut buf.as_slice();
+ while buf.has_remaining() {
+ let result = decode_varint(&mut buf);
+ debug_assert!(result.is_ok());
+ criterion::black_box(&result);
+ }
+ })
+ }
+ })
+ .throughput(Throughput::Bytes(decoded_len));
+
+ criterion
+ .benchmark_group(&name)
+ .bench_function("encoded_len", move |b| {
+ b.iter(|| {
+ let mut sum = 0;
+ for &value in &values {
+ sum += encoded_len_varint(value);
+ }
+ criterion::black_box(sum);
+ })
+ })
+ .throughput(Throughput::Bytes(decoded_len));
+}
+
+fn main() {
+ let mut criterion = Criterion::default().configure_from_args();
+
+ // Benchmark encoding and decoding 100 small (1 byte) varints.
+ benchmark_varint(&mut criterion, "small", (0..100).collect());
+
+ // Benchmark encoding and decoding 100 medium (5 byte) varints.
+ benchmark_varint(&mut criterion, "medium", (1 << 28..).take(100).collect());
+
+ // Benchmark encoding and decoding 100 large (10 byte) varints.
+ benchmark_varint(&mut criterion, "large", (1 << 63..).take(100).collect());
+
+ // Benchmark encoding and decoding 100 varints of mixed width (average 5.5 bytes).
+ benchmark_varint(
+ &mut criterion,
+ "mixed",
+ (0..10)
+ .flat_map(move |width| {
+ let exponent = width * 7;
+ (0..10).map(move |offset| offset + (1 << exponent))
+ })
+ .collect(),
+ );
+
+ criterion.final_summary();
+}