Skip to content

Commit

Permalink
Update rkyv to 0.8.3
Browse files Browse the repository at this point in the history
  • Loading branch information
djkoloski committed Sep 16, 2024
1 parent f83a991 commit dbc8d00
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 250 deletions.
4 changes: 1 addition & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ borsh = { version = "=1.5.1", features = ["derive"], optional = true }
# TODO: Unfork after bson adds support for pre-warmed serialization buffers
# https://github.com/mongodb/bson-rust/pull/328
bson = { version = "=2.9.0", git = "https://github.com/djkoloski/bson-rust", branch = "add_into_vec", optional = true }
bytecheck = { version = "=0.6.12", optional = true }
bytemuck = { version = "=1.16.1", optional = true }
capnp = { version = "=0.19.6", optional = true }
cbor4ii = { version = "=0.3.2", features = [ "use_std", "serde1" ], optional = true }
Expand All @@ -79,7 +78,7 @@ pot = { version = "=3.0.0", optional = true }
pprof = { version = "=0.13.0", features = ["flamegraph"], optional = true }
prost = { version = "=0.12.6", optional = true }
rand = "=0.8.5"
rkyv = { version = "=0.7.44", features = ["validation"], optional = true }
rkyv = { version = "=0.8.3", optional = true }
rmp-serde = { version = "=1.3.0", optional = true }
ron = { version = "=0.8.1", optional = true }
serde = { version = "=1.0.204", features = ["derive"], optional = true }
Expand All @@ -106,7 +105,6 @@ default = [
"bitcode",
"borsh",
"bson",
"bytecheck",
"bytemuck",
"capnp",
"cbor4ii",
Expand Down
126 changes: 90 additions & 36 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,26 +195,41 @@ fn bench_log(c: &mut Criterion) {
BENCH,
c,
&data,
|data| {
for log in data.logs.iter() {
|logs| {
for log in logs.logs.iter() {
black_box(&log.address);
black_box(log.code);
black_box(log.size);
}
},
|mut logs| {
use rust_serialization_benchmark::datasets::log::ArchivedAddress;

for i in 0..logs.as_ref().logs.len() {
let mut log = logs.as_mut().logs_pin().index_pin(i);
*log.as_mut().address_pin() = ArchivedAddress {
x0: 0,
x1: 0,
x2: 0,
x3: 0,
};
*log.as_mut().code_pin() = 200;
*log.as_mut().size_pin() = 0;
|log| {
use rkyv::{munge::munge, vec::ArchivedVec};
use rust_serialization_benchmark::datasets::log::{
ArchivedAddress, ArchivedLog, ArchivedLogs,
};

munge!(let ArchivedLogs { logs } = log);
let mut logs = ArchivedVec::as_slice_seal(logs);
for i in 0..logs.len() {
munge! {
let ArchivedLog {
address: ArchivedAddress {
mut x0,
mut x1,
mut x2,
mut x3,
},
mut code,
mut size,
..
} = logs.as_mut().index(i);
}
*x0 = 0;
*x1 = 0;
*x2 = 0;
*x3 = 0;
*code = 200.into();
*size = 0.into();
}
},
);
Expand Down Expand Up @@ -374,12 +389,29 @@ fn bench_mesh(c: &mut Criterion) {
black_box(&triangle.normal);
}
},
|mut mesh| {
for i in 0..mesh.as_ref().triangles.len() {
let mut triangle = mesh.as_mut().triangles_pin().index_pin(i);
triangle.normal.x = 0f32;
triangle.normal.y = 0f32;
triangle.normal.z = 0f32;
|mesh| {
use rkyv::{munge::munge, vec::ArchivedVec};
use rust_serialization_benchmark::datasets::mesh::{
ArchivedMesh, ArchivedTriangle, ArchivedVector3,
};

munge!(let ArchivedMesh { triangles } = mesh);
let mut triangles = ArchivedVec::as_slice_seal(triangles);

for i in 0..triangles.len() {
munge! {
let ArchivedTriangle {
normal: ArchivedVector3 {
mut x,
mut y,
mut z,
},
..
} = triangles.as_mut().index(i);
}
*x = 0f32.into();
*y = 0f32.into();
*z = 0f32.into();
}
},
);
Expand Down Expand Up @@ -534,20 +566,36 @@ fn bench_minecraft_savedata(c: &mut Criterion) {
BENCH,
c,
&data,
|data| {
for player in data.players.iter() {
|players| {
for player in players.players.iter() {
black_box(&player.game_type);
}
},
|mut players| {
|players| {
use rkyv::{munge::munge, vec::ArchivedVec};
use rust_serialization_benchmark::datasets::minecraft_savedata::{
ArchivedPlayer, ArchivedPlayers,
};

use rust_serialization_benchmark::datasets::minecraft_savedata::ArchivedGameType;

for i in 0..players.as_ref().players.len() {
let mut player = players.as_mut().players_pin().index_pin(i);
*player.as_mut().game_type_pin() = ArchivedGameType::Survival;
*player.as_mut().spawn_x_pin() = 0;
*player.as_mut().spawn_y_pin() = 0;
*player.as_mut().spawn_z_pin() = 0;
munge!(let ArchivedPlayers { players } = players);
let mut players = ArchivedVec::as_slice_seal(players);

for i in 0..players.len() {
munge! {
let ArchivedPlayer {
mut game_type,
mut spawn_x,
mut spawn_y,
mut spawn_z,
..
} = players.as_mut().index(i);
}
*game_type = ArchivedGameType::Survival;
*spawn_x = 0.into();
*spawn_y = 0.into();
*spawn_z = 0.into();
}
},
);
Expand Down Expand Up @@ -703,15 +751,21 @@ fn bench_mk48(c: &mut Criterion) {
BENCH,
c,
&data,
|data| {
for update in data.updates.iter() {
|updates| {
for update in updates.updates.iter() {
black_box(update.score);
}
},
|mut updates| {
for i in 0..updates.as_ref().updates.len() {
let mut update = updates.as_mut().updates_pin().index_pin(i);
*update.as_mut().score_pin() *= 2;
|updates| {
use rkyv::{munge::munge, vec::ArchivedVec};
use rust_serialization_benchmark::datasets::mk48::{ArchivedUpdate, ArchivedUpdates};

munge!(let ArchivedUpdates { updates } = updates);
let mut updates = ArchivedVec::as_slice_seal(updates);

for i in 0..updates.len() {
munge!(let ArchivedUpdate { mut score, .. } = updates.as_mut().index(i));
*score *= 2;
}
},
);
Expand Down
122 changes: 36 additions & 86 deletions src/bench_rkyv.rs
Original file line number Diff line number Diff line change
@@ -1,111 +1,73 @@
use core::pin::Pin;
use core::mem::take;

use bytecheck::CheckBytes;
use criterion::{black_box, Criterion};
use rkyv::{
archived_value, archived_value_mut, check_archived_value,
ser::{
serializers::{AlignedSerializer, BufferScratch, CompositeSerializer},
Serializer,
},
validation::validators::DefaultValidator,
AlignedVec, Archive, Deserialize, Infallible, Serialize,
access, access_unchecked, access_unchecked_mut,
api::high::{to_bytes_in, HighDeserializer, HighSerializer, HighValidator},
bytecheck::CheckBytes,
deserialize, from_bytes,
rancor::Failure,
seal::Seal,
ser::allocator::ArenaHandle,
util::AlignedVec,
Archive, Deserialize, Serialize,
};

pub type BenchSerializer<'a> = CompositeSerializer<
AlignedSerializer<&'a mut AlignedVec>,
BufferScratch<&'a mut AlignedVec>,
Infallible,
>;
pub type BenchSerializer<'a> = HighSerializer<'a, AlignedVec, ArenaHandle<'a>, Failure>;
pub type BenchDeserializer = HighDeserializer<Failure>;
pub type BenchValidator<'a> = HighValidator<'a, Failure>;

pub fn bench<T, R, U>(name: &'static str, c: &mut Criterion, data: &T, read: R, update: U)
where
T: Archive + for<'a> Serialize<BenchSerializer<'a>> + PartialEq,
T::Archived: for<'a> CheckBytes<DefaultValidator<'a>> + Deserialize<T, Infallible>,
T::Archived: for<'a> CheckBytes<BenchValidator<'a>> + Deserialize<T, BenchDeserializer>,
R: Fn(&T::Archived),
U: Fn(Pin<&mut T::Archived>),
<T as Archive>::Archived: for<'a> rkyv::CheckBytes<DefaultValidator<'a>>,
U: for<'a> Fn(Seal<'a, T::Archived>),
<T as Archive>::Archived: for<'a> CheckBytes<BenchValidator<'a>>,
{
const BUFFER_LEN: usize = 10_000_000;
const SCRATCH_LEN: usize = 512_000;

let mut group = c.benchmark_group(format!("{}/rkyv", name));

let mut serialize_buffer = AlignedVec::with_capacity(BUFFER_LEN);
let mut serialize_scratch = AlignedVec::with_capacity(SCRATCH_LEN);
unsafe {
serialize_scratch.set_len(SCRATCH_LEN);
}
let mut buffer = AlignedVec::with_capacity(BUFFER_LEN);

group.bench_function("serialize", |b| {
b.iter(|| {
serialize_buffer.clear();

let mut serializer = CompositeSerializer::new(
AlignedSerializer::new(black_box(&mut serialize_buffer)),
BufferScratch::new(black_box(&mut serialize_scratch)),
Infallible,
);
black_box(serializer.serialize_value(black_box(data)).unwrap());
buffer.clear();
buffer = black_box(to_bytes_in(black_box(data), black_box(take(&mut buffer))).unwrap());
})
});

serialize_buffer.clear();
let mut serializer = CompositeSerializer::new(
AlignedSerializer::new(&mut serialize_buffer),
BufferScratch::new(&mut serialize_scratch),
Infallible,
);
let pos = serializer.serialize_value(data).unwrap();
let deserialize_buffer = serializer.into_serializer().into_inner();
buffer.clear();
buffer = black_box(to_bytes_in(black_box(data), black_box(buffer)).unwrap());

group.bench_function("access (unvalidated)", |b| {
b.iter(|| {
black_box(unsafe {
archived_value::<T>(black_box(deserialize_buffer.as_ref()), black_box(pos))
});
})
b.iter(|| black_box(unsafe { access_unchecked::<T::Archived>(black_box(buffer.as_ref())) }))
});

group.bench_function("access (validated upfront with error)", |b| {
b.iter(|| {
black_box(
check_archived_value::<T>(black_box(deserialize_buffer.as_ref()), black_box(pos))
.unwrap(),
);
})
b.iter(|| black_box(access::<T::Archived, Failure>(black_box(buffer.as_ref())).unwrap()))
});

group.bench_function("read (unvalidated)", |b| {
b.iter(|| {
unsafe {
read(archived_value::<T>(
black_box(deserialize_buffer.as_ref()),
black_box(pos),
))
};
black_box(());
black_box(unsafe { read(access_unchecked::<T::Archived>(black_box(buffer.as_ref()))) })
})
});

group.bench_function("read (validated upfront with error)", |b| {
b.iter(|| {
read(
check_archived_value::<T>(black_box(deserialize_buffer.as_ref()), black_box(pos))
.unwrap(),
);
black_box(());
black_box(read(
access::<T::Archived, Failure>(black_box(buffer.as_ref())).unwrap(),
))
})
});

let mut update_buffer = deserialize_buffer.clone();
group.bench_function("update", |b| {
let mut update_buffer = buffer.clone();
group.bench_function("update (unvalidated)", |b| {
b.iter(|| {
let mut value = unsafe {
archived_value_mut::<T>(
black_box(Pin::new_unchecked(update_buffer.as_mut_slice())),
black_box(pos),
)
access_unchecked_mut::<T::Archived>(black_box(update_buffer.as_mut_slice()))
};
update(value.as_mut());
black_box(value);
Expand All @@ -114,33 +76,21 @@ where

group.bench_function("deserialize (unvalidated)", |b| {
b.iter(|| {
let value = unsafe {
archived_value::<T>(black_box(deserialize_buffer.as_ref()), black_box(pos))
};
let deserialized: T = value.deserialize(&mut Infallible).unwrap();
black_box(deserialized);
let value = unsafe { access_unchecked::<T::Archived>(black_box(buffer.as_ref())) };
black_box(deserialize(value).unwrap())
})
});

group.bench_function("deserialize (validated upfront with error)", |b| {
b.iter(|| {
let value =
check_archived_value::<T>(black_box(deserialize_buffer.as_ref()), black_box(pos))
.unwrap();
let deserialized: T = value.deserialize(&mut Infallible).unwrap();
black_box(deserialized);
let value = access::<T::Archived, Failure>(black_box(buffer.as_ref())).unwrap();
black_box(deserialize(value).unwrap())
})
});

crate::bench_size(name, "rkyv", deserialize_buffer);
crate::bench_size(name, "rkyv", &buffer);

assert!(
check_archived_value::<T>(deserialize_buffer.as_ref(), pos)
.unwrap()
.deserialize(&mut Infallible)
.unwrap()
== *data
);
assert!(from_bytes::<T, Failure>(buffer.as_ref()).unwrap() == *data);

group.finish();
}
Loading

0 comments on commit dbc8d00

Please sign in to comment.