Skip to content

Commit

Permalink
Tweak inline hints
Browse files Browse the repository at this point in the history
  • Loading branch information
zakarumych committed Dec 28, 2023
1 parent 3998c7c commit 99a5b68
Show file tree
Hide file tree
Showing 14 changed files with 345 additions and 52 deletions.
11 changes: 7 additions & 4 deletions benchmark/benches/benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
buffer.resize(buffer.capacity(), 0);
let rng = SmallRng::seed_from_u64(42);

const LEN: usize = 2000;
const LEN: usize = 100;
let mut size = 0;

{
Expand Down Expand Up @@ -265,12 +265,13 @@ pub fn criterion_benchmark(c: &mut Criterion) {
{
let mut group = c.benchmark_group("net-packet/rkyv");
let mut rkyv_ser = rkyv::ser::serializers::AllocSerializer::<1024>::default();
let mut pos = 0;

group.bench_function("serialize", |b| {
b.iter(|| {
use rkyv::ser::Serializer;

rkyv_ser
pos = rkyv_ser
.serialize_value(&NetPacket {
game_messages: messages(rng.clone(), black_box(LEN)).collect(),
})
Expand All @@ -281,7 +282,8 @@ pub fn criterion_benchmark(c: &mut Criterion) {
let vec: rkyv::AlignedVec = rkyv_ser.into_serializer().into_inner();
group.bench_function("read", |b| {
b.iter(|| {
let packet = rkyv::check_archived_root::<NetPacket<GameMessage>>(&vec[..]).unwrap();
let packet =
rkyv::check_archived_value::<NetPacket<GameMessage>>(&vec[..], pos).unwrap();

for message in packet.game_messages.iter() {
match message {
Expand Down Expand Up @@ -314,7 +316,8 @@ pub fn criterion_benchmark(c: &mut Criterion) {
b.iter(|| {
use rkyv::Deserialize;
let archive =
rkyv::check_archived_root::<NetPacket<GameMessage>>(&vec[..]).unwrap();
rkyv::check_archived_value::<NetPacket<GameMessage>>(&vec[..], pos).unwrap();

let packet: NetPacket<GameMessage> =
archive.deserialize(&mut rkyv::Infallible).unwrap();

Expand Down
292 changes: 292 additions & 0 deletions examples/_profile.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,292 @@
extern crate alkahest;

extern crate rand;

#[cfg(feature = "speedy")]
extern crate speedy;

use std::hint::black_box;

use alkahest::{alkahest, Deserialize, Formula, Lazy, SerIter, Serialize};

use rand::{
distributions::{Alphanumeric, DistString},
rngs::SmallRng,
Rng, SeedableRng,
};

#[derive(Debug, Clone, Formula, Serialize, Deserialize)]
#[cfg_attr(feature = "speedy", derive(speedy::Writable, speedy::Readable))]
pub enum GameMessage {
Client(ClientMessage),
Server(ServerMessage),
}

#[derive(Debug)]
#[cfg_attr(feature = "speedy", derive(speedy::Readable))]
#[alkahest(Deserialize<'de, GameMessage>)]
pub enum GameMessageRead<'de> {
Client(ClientMessageRead<'de>),
Server(ServerMessageRead<'de>),
}

#[derive(Debug, Clone, Formula, Serialize, Deserialize)]
#[cfg_attr(feature = "speedy", derive(speedy::Writable, speedy::Readable))]
pub enum ClientMessage {
ClientData { nickname: String, clan: String },
Chat(String),
}

#[derive(Debug)]
#[cfg_attr(feature = "speedy", derive(speedy::Readable))]
#[alkahest(Deserialize<'de, ClientMessage>)]
pub enum ClientMessageRead<'de> {
ClientData { nickname: &'de str, clan: &'de str },
Chat(&'de str),
}

#[derive(Debug, Clone, Formula, Serialize, Deserialize)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "speedy", derive(speedy::Writable, speedy::Readable))]
pub enum ServerMessage {
ServerData(u64),
ClientChat { client_id: u64, message: String },
}

#[derive(Debug)]
#[cfg_attr(feature = "speedy", derive(speedy::Readable))]
#[alkahest(Deserialize<'de, ServerMessage>)]
pub enum ServerMessageRead<'de> {
ServerData(u64),
ClientChat { client_id: u64, message: &'de str },
}

#[derive(Debug, Formula, Serialize, Deserialize)]
#[cfg_attr(feature = "speedy", derive(speedy::Writable, speedy::Readable))]
pub struct NetPacket<G> {
pub game_messages: Vec<G>,
}

#[derive(Debug)]
#[alkahest(for<X: Formula> Serialize<NetPacket<X>> where G: Serialize<[X]>)]
pub struct NetPacketWrite<G> {
pub game_messages: G,
}

#[derive(Debug)]
#[alkahest(Deserialize<'de, NetPacket<G>> where G: Formula)]
pub struct NetPacketRead<'de, G> {
pub game_messages: Lazy<'de, [G]>,
}

fn get_string(rng: &mut impl Rng) -> String {
Alphanumeric.sample_string(rng, 8)
}

struct BenchIter {
len: usize,
}

impl BenchIter {
fn iter<F>(self, mut f: F)
where
F: FnMut(),
{
for _ in 0..self.len {
f();
}
}
}

fn bench_function<F>(_name: &str, f: F)
where
F: FnOnce(BenchIter),
{
f(BenchIter { len: 100_000 });
}

fn messages<'a>(mut rng: impl Rng + 'a, len: usize) -> impl Iterator<Item = GameMessage> + 'a {
core::iter::repeat_with(move || match rng.gen_range(0..4) {
0 => GameMessage::Client(ClientMessage::ClientData {
nickname: get_string(&mut rng),
clan: get_string(&mut rng),
}),
1 => GameMessage::Client(ClientMessage::Chat(get_string(&mut rng))),
2 => GameMessage::Server(ServerMessage::ClientChat {
client_id: rng.gen(),
message: get_string(&mut rng),
}),
3 => GameMessage::Server(ServerMessage::ServerData(rng.gen_range(0..10))),
_ => unreachable!(),
})
.take(len)
// Make size unpredictable for `FromIterator` as this is common in real-world.
.filter(|msg| !matches!(msg, GameMessage::Server(ServerMessage::ServerData(3..=10))))
}

pub fn main() {
let mut buffer = Vec::with_capacity(1 << 14);
buffer.resize(buffer.capacity(), 0);
let rng = SmallRng::seed_from_u64(42);

const LEN: usize = 100;
let mut size = 0;

{
bench_function("serialize", |b| {
b.iter(|| {
size = alkahest::serialize_to_vec::<NetPacket<GameMessage>, _>(
NetPacketWrite {
game_messages: SerIter(messages(rng.clone(), black_box(LEN))),
},
&mut buffer,
)
.0;
})
});

bench_function("read", |b| {
b.iter(|| {
let packet = alkahest::deserialize::<
NetPacket<GameMessage>,
NetPacketRead<GameMessage>,
>(&buffer[..size])
.unwrap();

for message in packet.game_messages.iter::<GameMessageRead>() {
match message.unwrap() {
GameMessageRead::Client(ClientMessageRead::ClientData {
nickname,
clan,
}) => {
black_box(nickname);
black_box(clan);
}
GameMessageRead::Client(ClientMessageRead::Chat(message)) => {
black_box(message);
}
GameMessageRead::Server(ServerMessageRead::ServerData(data)) => {
black_box(data);
}
GameMessageRead::Server(ServerMessageRead::ClientChat {
client_id,
message,
}) => {
black_box(client_id);
black_box(message);
}
}
}
})
});

bench_function("deserialize", |b| {
b.iter(|| {
let packet =
alkahest::deserialize::<NetPacket<GameMessage>, NetPacket<GameMessage>>(
&buffer[..size],
)
.unwrap();

for message in packet.game_messages.iter() {
match message {
GameMessage::Client(ClientMessage::ClientData { nickname, clan }) => {
black_box(nickname);
black_box(clan);
}
GameMessage::Client(ClientMessage::Chat(message)) => {
black_box(message);
}
GameMessage::Server(ServerMessage::ServerData(data)) => {
black_box(data);
}
GameMessage::Server(ServerMessage::ClientChat { client_id, message }) => {
black_box(client_id);
black_box(message);
}
}
}
})
});
}

#[cfg(feature = "speedy")]
{
let mut group = c.benchmark_group("net-packet/speedy");

buffer.clear();
buffer.resize(buffer.capacity(), 0);

bench_function("serialize", |b| {
b.iter(|| {
speedy::Writable::write_to_buffer(
&NetPacket {
game_messages: messages(rng.clone(), black_box(LEN)).collect(),
},
&mut buffer,
)
.unwrap();
})
});

bench_function("read", |b| {
b.iter(|| {
let packet =
<NetPacket<GameMessageRead> as speedy::Readable<_>>::read_from_buffer(&buffer)
.unwrap();

for message in packet.game_messages.iter() {
match message {
GameMessageRead::Client(ClientMessageRead::ClientData {
nickname,
clan,
}) => {
black_box(nickname);
black_box(clan);
}
GameMessageRead::Client(ClientMessageRead::Chat(message)) => {
black_box(message);
}
GameMessageRead::Server(ServerMessageRead::ServerData(data)) => {
black_box(data);
}
GameMessageRead::Server(ServerMessageRead::ClientChat {
client_id,
message,
}) => {
black_box(client_id);
black_box(message);
}
}
}
})
});

bench_function("deserialize", |b| {
b.iter(|| {
let packet =
<NetPacket<GameMessage> as speedy::Readable<_>>::read_from_buffer(&buffer)
.unwrap();

for message in packet.game_messages.iter() {
match message {
GameMessage::Client(ClientMessage::ClientData { nickname, clan }) => {
black_box(nickname);
black_box(clan);
}
GameMessage::Client(ClientMessage::Chat(message)) => {
black_box(message);
}
GameMessage::Server(ServerMessage::ServerData(data)) => {
black_box(data);
}
GameMessage::Server(ServerMessage::ClientChat { client_id, message }) => {
black_box(client_id);
black_box(message);
}
}
}
})
});
}
}
8 changes: 4 additions & 4 deletions proc/src/deserialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ pub fn derive(args: DeserializeArgs, input: &syn::DeriveInput) -> syn::Result<To
deserialize_generics.split_for_impl();
Ok(quote::quote! {
impl #impl_deserialize_generics ::alkahest::private::Deserialize<#de, #formula_path> for #ident #type_generics #where_serialize_clause {
#[inline(always)]
#[inline]
fn deserialize(mut de: ::alkahest::private::Deserializer<#de>) -> ::alkahest::private::Result<Self, ::alkahest::private::DeserializeError> {
#field_checks

Expand All @@ -306,7 +306,7 @@ pub fn derive(args: DeserializeArgs, input: &syn::DeriveInput) -> syn::Result<To
::alkahest::private::Result::Ok(value)
}

#[inline(always)]
#[inline]
fn deserialize_in_place(&mut self, mut de: ::alkahest::private::Deserializer<#de>) -> Result<(), ::alkahest::private::DeserializeError> {
#field_checks

Expand Down Expand Up @@ -475,7 +475,7 @@ pub fn derive(args: DeserializeArgs, input: &syn::DeriveInput) -> syn::Result<To
deserialize_generics.split_for_impl();
Ok(quote::quote! {
impl #impl_deserialize_generics ::alkahest::private::Deserialize<#de, #formula_path> for #ident #type_generics #where_serialize_clause {
#[inline(always)]
#[inline]
fn deserialize(mut de: ::alkahest::private::Deserializer<#de>) -> ::alkahest::private::Result<Self, ::alkahest::private::DeserializeError> {
#field_checks

Expand All @@ -500,7 +500,7 @@ pub fn derive(args: DeserializeArgs, input: &syn::DeriveInput) -> syn::Result<To
}
}

#[inline(always)]
#[inline]
fn deserialize_in_place(&mut self, mut de: ::alkahest::private::Deserializer<#de>) -> Result<(), ::alkahest::private::DeserializeError> {
#field_checks

Expand Down
Loading

0 comments on commit 99a5b68

Please sign in to comment.