Benchmarks; safety
This commit is contained in:
parent
6033968a13
commit
b712110590
|
@ -1,18 +1,25 @@
|
|||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use oo::BinarySource;
|
||||
use oo::BytesBinarySource;
|
||||
use oo::Domain;
|
||||
use oo::IOBinarySource;
|
||||
use oo::IOValueDomainCodec;
|
||||
use oo::IOValues;
|
||||
use oo::PackedWriter;
|
||||
use oo::PlainValue;
|
||||
use oo::Reader;
|
||||
use oo::ValueImpl;
|
||||
use oo::packed::annotated_iovalue_from_bytes;
|
||||
use oo::packed::view::ViewIterator;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::io::Seek;
|
||||
use std::io;
|
||||
|
||||
fn deep_standalone_copy<D: Domain, V: ValueImpl<D>>(v: V) -> PlainValue<'static, D> {
|
||||
oo::copy_via(&v, &mut |d| Ok::<_, ()>(oo::owned(oo::Embedded::new(d.clone())))).unwrap()
|
||||
}
|
||||
|
||||
pub fn bench_decoder_bytes(c: &mut Criterion) {
|
||||
let mut fh = File::open("../../../tests/samples.bin").unwrap();
|
||||
let mut bs = vec![];
|
||||
|
@ -87,12 +94,109 @@ pub fn large_testdata_encoder(c: &mut Criterion) {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn large_testdata_decoder_view(c: &mut Criterion) {
|
||||
c.bench_function("(oo) view-decode testdata.bin", |b| {
|
||||
let mut fh = File::open("benches/testdata.bin").unwrap();
|
||||
let mut bs = vec![];
|
||||
fh.read_to_end(&mut bs).ok();
|
||||
b.iter(|| {
|
||||
let mut r = ViewIterator::new(&bs);
|
||||
while let Some(_) = r.next() {}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
pub fn large_testdata_decoder_view_clone(c: &mut Criterion) {
|
||||
c.bench_function("(oo) view-decode testdata.bin with cloning", |b| {
|
||||
let mut fh = File::open("benches/testdata.bin").unwrap();
|
||||
let mut bs = vec![];
|
||||
fh.read_to_end(&mut bs).ok();
|
||||
b.iter(|| {
|
||||
let mut r = ViewIterator::new(&bs);
|
||||
while let Some(v) = r.next() {
|
||||
v.value_clone();
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
pub fn large_testdata_decoder_view_deepcopy(c: &mut Criterion) {
|
||||
c.bench_function("(oo) view-decode testdata.bin with deep copy", |b| {
|
||||
let mut fh = File::open("benches/testdata.bin").unwrap();
|
||||
let mut bs = vec![];
|
||||
fh.read_to_end(&mut bs).ok();
|
||||
b.iter(|| {
|
||||
let mut r = ViewIterator::new(&bs);
|
||||
while let Some(v) = r.next() {
|
||||
deep_standalone_copy(&*v);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
pub fn large_testdata_encoder_view(c: &mut Criterion) {
|
||||
c.bench_function("(oo) view-encode testdata.bin", |b| {
|
||||
let mut fh = io::BufReader::new(File::open("benches/testdata.bin").unwrap());
|
||||
let mut bs = vec![];
|
||||
fh.read_to_end(&mut bs).ok();
|
||||
let vs = ViewIterator::new(&bs).collect::<Vec<_>>();
|
||||
b.iter_with_large_drop(|| {
|
||||
let mut bs = vec![];
|
||||
let mut w = PackedWriter::new(&mut bs);
|
||||
let mut enc = IOValueDomainCodec;
|
||||
for v in &vs {
|
||||
v.write(&mut w, &mut enc).unwrap();
|
||||
}
|
||||
bs
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
pub fn large_testdata_encoder_view_clone(c: &mut Criterion) {
|
||||
c.bench_function("(oo) view-encode testdata.bin with cloning", |b| {
|
||||
let mut fh = io::BufReader::new(File::open("benches/testdata.bin").unwrap());
|
||||
let mut bs = vec![];
|
||||
fh.read_to_end(&mut bs).ok();
|
||||
let vs = ViewIterator::new(&bs).map(|v| v.value_clone()).collect::<Vec<_>>();
|
||||
b.iter_with_large_drop(|| {
|
||||
let mut bs = vec![];
|
||||
let mut w = PackedWriter::new(&mut bs);
|
||||
let mut enc = IOValueDomainCodec;
|
||||
for v in &vs {
|
||||
v.write(&mut w, &mut enc).unwrap();
|
||||
}
|
||||
bs
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
pub fn large_testdata_encoder_view_deepcopy(c: &mut Criterion) {
|
||||
c.bench_function("(oo) view-encode testdata.bin with deep copy", |b| {
|
||||
let mut fh = io::BufReader::new(File::open("benches/testdata.bin").unwrap());
|
||||
let mut bs = vec![];
|
||||
fh.read_to_end(&mut bs).ok();
|
||||
let vs = ViewIterator::new(&bs).map(|v| deep_standalone_copy(&*v)).collect::<Vec<_>>();
|
||||
b.iter_with_large_drop(|| {
|
||||
let mut bs = vec![];
|
||||
let mut w = PackedWriter::new(&mut bs);
|
||||
let mut enc = IOValueDomainCodec;
|
||||
for v in &vs {
|
||||
v.write(&mut w, &mut enc).unwrap();
|
||||
}
|
||||
bs
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(codec,
|
||||
bench_decoder_bytes, bench_decoder_file, bench_decoder_buffered_file,
|
||||
bench_encoder);
|
||||
criterion_group!{
|
||||
name = large_testdata;
|
||||
config = Criterion::default().sample_size(10);
|
||||
targets = large_testdata_decoder_with_ann, large_testdata_decoder_without_ann, large_testdata_encoder
|
||||
targets =
|
||||
large_testdata_decoder_with_ann, large_testdata_decoder_without_ann, large_testdata_encoder,
|
||||
large_testdata_decoder_view, large_testdata_decoder_view_clone, large_testdata_decoder_view_deepcopy,
|
||||
large_testdata_encoder_view, large_testdata_encoder_view_clone, large_testdata_encoder_view_deepcopy
|
||||
}
|
||||
criterion_main!(codec, large_testdata);
|
||||
|
|
|
@ -82,10 +82,16 @@ fn skip_value(packed: &[u8], mut i: usize) -> io::Result<usize> {
|
|||
}
|
||||
Tag::SmallInteger(_) => i + 1,
|
||||
Tag::MediumInteger(n) => i + 1 + (n as usize),
|
||||
Tag::SignedInteger | Tag::String | Tag:: ByteString | Tag:: Symbol => {
|
||||
Tag::SignedInteger | Tag::ByteString => {
|
||||
let (n, i) = varint(packed, i + 1)?;
|
||||
i + (n as usize)
|
||||
}
|
||||
Tag::String | Tag::Symbol => {
|
||||
let (n, i) = varint(packed, i + 1)?;
|
||||
std::str::from_utf8(&packed[i .. i + (n as usize)]).map_err(
|
||||
|_| io::Error::new(io::ErrorKind::InvalidData, "Invalid UTF-8"))?;
|
||||
i + (n as usize)
|
||||
}
|
||||
Tag::Record | Tag::Sequence | Tag::Set | Tag::Dictionary => {
|
||||
i = i + 1;
|
||||
while tag_at(packed, i)? != Tag::End {
|
||||
|
@ -224,7 +230,10 @@ impl<'de, Packed: AsRef<[u8]> + 'de> ValueImpl<IOValue> for View<'de, Packed> {
|
|||
|
||||
fn as_string(&self) -> Option<Cow<'_, str>> {
|
||||
match self.tag() {
|
||||
Tag::String => Some(Cow::Borrowed(std::str::from_utf8(self.atom_chunk()).unwrap())),
|
||||
Tag::String => Some(Cow::Borrowed(unsafe {
|
||||
// SAFETY: we already checked in the View constructor
|
||||
std::str::from_utf8_unchecked(self.atom_chunk())
|
||||
})),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -238,7 +247,10 @@ impl<'de, Packed: AsRef<[u8]> + 'de> ValueImpl<IOValue> for View<'de, Packed> {
|
|||
|
||||
fn as_symbol(&self) -> Option<Cow<'_, str>> {
|
||||
match self.tag() {
|
||||
Tag::Symbol => Some(Cow::Borrowed(std::str::from_utf8(self.atom_chunk()).unwrap())),
|
||||
Tag::Symbol => Some(Cow::Borrowed(unsafe {
|
||||
// SAFETY: we already checked in the View constructor
|
||||
std::str::from_utf8_unchecked(self.atom_chunk())
|
||||
})),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -265,7 +277,7 @@ impl<'de, Packed: AsRef<[u8]> + 'de> ValueImpl<IOValue> for View<'de, Packed> {
|
|||
}
|
||||
|
||||
fn iter(&self) -> Box<dyn Iterator<Item = Value<'_, IOValue>> + '_> {
|
||||
let mut i = Box::new(ViewIterator::new(&self.packed.as_ref()[self.value_offset + 1 ..]));
|
||||
let mut i = Box::new(ViewIterator::new(&self.packed.as_ref()[self.value_offset + 1 .. self.value_end]));
|
||||
match self.tag() {
|
||||
Tag::Record => { i.next(); () }
|
||||
Tag::Sequence => (),
|
||||
|
@ -296,7 +308,7 @@ impl<'de, Packed: AsRef<[u8]> + 'de> ValueImpl<IOValue> for View<'de, Packed> {
|
|||
|
||||
fn entries(&self) -> Box<dyn Iterator<Item = (Value<'_, IOValue>, Value<'_, IOValue>)> + '_> {
|
||||
if !self.is_dictionary() { panic!("Not a dictionary") }
|
||||
Box::new(DictionaryAdapter(ViewIterator::new(&self.packed.as_ref()[self.value_offset + 1 ..])))
|
||||
Box::new(DictionaryAdapter(ViewIterator::new(&self.packed.as_ref()[self.value_offset + 1 .. self.value_end])))
|
||||
}
|
||||
|
||||
fn is_embedded(&self) -> bool {
|
||||
|
|
Loading…
Reference in New Issue