blob: 6fa89b71bb5c24e1b648aa3469df5151b18a26bd [file]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
pub mod data;
pub mod serializers;
pub mod generated {
include!(concat!(env!("OUT_DIR"), "/protobuf.rs"));
}
use criterion::{black_box, Criterion};
use data::{
MediaContent, MediaContentList, NumericStruct, NumericStructList, Sample, SampleList,
SchemaMismatchCase,
};
use serializers::{
fory::{schema_mismatch_enabled, ForySerializer},
msgpack::MsgpackSerializer,
protobuf::ProtobufSerializer,
BenchmarkSerializer,
};
pub fn run_serialization_benchmarks(c: &mut Criterion) {
let fory_serializer = ForySerializer::new();
let protobuf_serializer = ProtobufSerializer::new();
let msgpack_serializer = MsgpackSerializer::new();
run_benchmark_case::<NumericStruct>(
c,
&fory_serializer,
&protobuf_serializer,
&msgpack_serializer,
);
run_benchmark_case::<Sample>(
c,
&fory_serializer,
&protobuf_serializer,
&msgpack_serializer,
);
run_benchmark_case::<MediaContent>(
c,
&fory_serializer,
&protobuf_serializer,
&msgpack_serializer,
);
run_benchmark_case::<NumericStructList>(
c,
&fory_serializer,
&protobuf_serializer,
&msgpack_serializer,
);
run_benchmark_case::<SampleList>(
c,
&fory_serializer,
&protobuf_serializer,
&msgpack_serializer,
);
run_benchmark_case::<MediaContentList>(
c,
&fory_serializer,
&protobuf_serializer,
&msgpack_serializer,
);
}
fn run_benchmark_case<T>(
c: &mut Criterion,
fory_serializer: &ForySerializer,
protobuf_serializer: &ProtobufSerializer,
msgpack_serializer: &MsgpackSerializer,
) where
T: SchemaMismatchCase,
ForySerializer: BenchmarkSerializer<T>,
ProtobufSerializer: BenchmarkSerializer<T>,
MsgpackSerializer: BenchmarkSerializer<T>,
{
let data = T::create();
let mismatch = schema_mismatch_enabled();
let mut group = c.benchmark_group(T::KIND.group_name());
group.bench_function("fory_serialize", |b| {
b.iter(|| {
let _ = black_box(fory_serializer.serialize(black_box(&data)).unwrap());
})
});
let fory_bytes = fory_serializer.serialize(&data).unwrap();
if mismatch {
let value: T::Read = fory_serializer.deserialize_value(&fory_bytes).unwrap();
T::verify_mismatch(&value, &data);
}
group.bench_function("fory_deserialize", |b| {
b.iter(|| {
if mismatch {
let value: T::Read = black_box(
fory_serializer
.deserialize_value(black_box(&fory_bytes))
.unwrap(),
);
black_box(value);
} else {
let value: T =
black_box(fory_serializer.deserialize(black_box(&fory_bytes)).unwrap());
black_box(value);
}
})
});
if !mismatch {
group.bench_function("protobuf_serialize", |b| {
b.iter(|| {
let _ = black_box(protobuf_serializer.serialize(black_box(&data)).unwrap());
})
});
let protobuf_bytes = protobuf_serializer.serialize(&data).unwrap();
group.bench_function("protobuf_deserialize", |b| {
b.iter(|| {
let value: T = black_box(
protobuf_serializer
.deserialize(black_box(&protobuf_bytes))
.unwrap(),
);
black_box(value);
})
});
group.bench_function("msgpack_serialize", |b| {
b.iter(|| {
let _ = black_box(msgpack_serializer.serialize(black_box(&data)).unwrap());
})
});
let msgpack_bytes = msgpack_serializer.serialize(&data).unwrap();
group.bench_function("msgpack_deserialize", |b| {
b.iter(|| {
let value: T = black_box(
msgpack_serializer
.deserialize(black_box(&msgpack_bytes))
.unwrap(),
);
black_box(value);
})
});
}
group.finish();
}
#[cfg(test)]
mod tests {
use super::*;
use crate::data::BenchmarkCase;
fn assert_round_trip<T>()
where
T: BenchmarkCase + std::fmt::Debug,
ForySerializer: BenchmarkSerializer<T>,
ProtobufSerializer: BenchmarkSerializer<T>,
MsgpackSerializer: BenchmarkSerializer<T>,
{
let value = T::create();
let fory_serializer = ForySerializer::new();
let fory_bytes = fory_serializer.serialize(&value).unwrap();
let decoded: T = fory_serializer.deserialize(&fory_bytes).unwrap();
assert_eq!(value, decoded);
let protobuf_serializer = ProtobufSerializer::new();
let protobuf_bytes = protobuf_serializer.serialize(&value).unwrap();
let decoded: T = protobuf_serializer.deserialize(&protobuf_bytes).unwrap();
assert_eq!(value, decoded);
let msgpack_serializer = MsgpackSerializer::new();
let msgpack_bytes = msgpack_serializer.serialize(&value).unwrap();
let decoded: T = msgpack_serializer.deserialize(&msgpack_bytes).unwrap();
assert_eq!(value, decoded);
}
fn assert_serialized_size<T>(
expected_fory: usize,
expected_protobuf: usize,
expected_msgpack: usize,
) where
T: BenchmarkCase,
ForySerializer: BenchmarkSerializer<T>,
ProtobufSerializer: BenchmarkSerializer<T>,
MsgpackSerializer: BenchmarkSerializer<T>,
{
let value = T::create();
let fory_bytes = ForySerializer::new().serialize(&value).unwrap();
let protobuf_bytes = ProtobufSerializer::new().serialize(&value).unwrap();
let msgpack_bytes = MsgpackSerializer::new().serialize(&value).unwrap();
assert_eq!(fory_bytes.len(), expected_fory);
assert_eq!(protobuf_bytes.len(), expected_protobuf);
assert_eq!(msgpack_bytes.len(), expected_msgpack);
}
#[test]
fn benchmark_cases_round_trip() {
assert_round_trip::<NumericStruct>();
assert_round_trip::<Sample>();
assert_round_trip::<MediaContent>();
assert_round_trip::<NumericStructList>();
assert_round_trip::<SampleList>();
assert_round_trip::<MediaContentList>();
}
#[test]
fn benchmark_serialized_sizes_match_baseline() {
assert_serialized_size::<NumericStruct>(78, 93, 87);
assert_serialized_size::<Sample>(445, 375, 590);
assert_serialized_size::<MediaContent>(362, 301, 500);
assert_serialized_size::<NumericStructList>(255, 475, 449);
assert_serialized_size::<SampleList>(1978, 1890, 2964);
assert_serialized_size::<MediaContentList>(1531, 1520, 2521);
}
}