use bebop::error::DeResult; use bebop::fixed_sized::FixedSized; use bebop::{define_serialize_chained, packed_read, SubRecord}; use bebop::{SliceWrapper, LEN_SIZE}; use criterion::{black_box, criterion_group, Criterion}; use std::convert::TryInto; /// a struct designed to be a nightmare for alignment #[repr(packed)] #[derive(Debug, Eq, PartialEq, Copy, Clone)] struct Fixed { a: u8, b: u64, } impl FixedSized for Fixed {} impl<'raw> SubRecord<'raw> for Fixed { const MIN_SERIALIZED_SIZE: usize = Self::SERIALIZED_SIZE; const EXACT_SERIALIZED_SIZE: Option = Some(Self::SERIALIZED_SIZE); fn serialized_size(&self) -> usize { Self::SERIALIZED_SIZE } define_serialize_chained!(*Fixed => |zelf, dest| { Ok(zelf.a._serialize_chained(dest)? + packed_read!(zelf.b)._serialize_chained(dest)?) }); fn _deserialize_chained(raw: &'raw [u8]) -> DeResult<(usize, Self)> { Ok(( 9, Self { a: raw[0], b: u64::from_le_bytes((raw[1..9]).try_into().unwrap()), }, )) } } fn cooked_array() -> Vec { (0..512u64) .map(|i| Fixed { a: (i % 255) as u8, b: i * 871 + i, }) .collect() } fn getter(c: &mut Criterion) { let cooked = cooked_array(); let raw = { let len = Fixed::SERIALIZED_SIZE * 512 + LEN_SIZE; let mut buf = Vec::with_capacity(len); assert_eq!(cooked._serialize_chained(&mut buf).unwrap(), len); buf }; let sw = >::from_raw(&raw[LEN_SIZE..]); c.bench_function("SliceWrapper get cooked struct", |b| { b.iter(|| { for i in 0..512 { sw.get(black_box(i)).unwrap(); } }) }); let sw = >::from_cooked(&cooked); c.bench_function("SliceWrapper get cooked struct", |b| { b.iter(|| { for i in 0..512 { sw.get(black_box(i)).unwrap(); } }) }); } criterion_group!(benches, getter);