diff --git a/Cargo.toml b/Cargo.toml index ac20718..e319053 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -92,6 +92,8 @@ simd-json-derive = { version = "=0.13.0", optional = true } speedy = { version = "=0.8.7", optional = true } savefile = { version = "=0.16.5", optional = true } savefile-derive = { version = "=0.16.5", optional = true } +tokio = { version = "1.37", features = ["full"], optional = true } +wiring = { version = "0.1", optional = true } zstd = "=0.12.4" [features] @@ -130,13 +132,15 @@ default = [ "serde_json", "simd-json", "speedy", - "savefile" + "savefile", + "wiring" ] capnp = ["dep:capnp"] prost = ["dep:capnp", "dep:prost"] simd-json = ["dep:simd-json", "simd-json-derive"] savefile = ["dep:savefile", "savefile-derive"] scale = ["parity-scale-codec", "parity-scale-codec-derive"] +wiring = ["dep:wiring", "dep:tokio", "criterion/async_tokio"] # Enable these features to regenerate generated files rather than using the committed versions. regenerate-capnp = ["dep:capnpc"] diff --git a/benches/bench.rs b/benches/bench.rs index 67612b3..eff0044 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -61,6 +61,8 @@ use rust_serialization_benchmark::bench_serde_json; use rust_serialization_benchmark::bench_simd_json; #[cfg(feature = "speedy")] use rust_serialization_benchmark::bench_speedy; +#[cfg(feature = "wiring")] +use rust_serialization_benchmark::bench_wiring; use rust_serialization_benchmark::generate_vec; @@ -243,6 +245,9 @@ fn bench_log(c: &mut Criterion) { #[cfg(feature = "nanoserde")] bench_nanoserde::bench(BENCH, c, &data); + + #[cfg(feature = "wiring")] + bench_wiring::bench::(BENCH, c, &data); } fn bench_mesh(c: &mut Criterion) { @@ -405,6 +410,9 @@ fn bench_mesh(c: &mut Criterion) { #[cfg(feature = "nanoserde")] bench_nanoserde::bench(BENCH, c, &data); + + #[cfg(feature = "wiring")] + bench_wiring::bench::(BENCH, c, &data); } fn bench_minecraft_savedata(c: &mut Criterion) { @@ -570,6 +578,9 @@ fn bench_minecraft_savedata(c: &mut Criterion) { #[cfg(feature = "nanoserde")] bench_nanoserde::bench(BENCH, c, &data); + + #[cfg(feature = "wiring")] + bench_wiring::bench::(BENCH, c, &data); } fn bench_mk48(c: &mut Criterion) { @@ -731,6 +742,9 @@ fn bench_mk48(c: &mut Criterion) { #[cfg(feature = "nanoserde")] bench_nanoserde::bench(BENCH, c, &data); + + #[cfg(feature = "wiring")] + bench_wiring::bench::(BENCH, c, &data); } #[cfg(feature = "pprof")] diff --git a/src/bench_wiring.rs b/src/bench_wiring.rs new file mode 100644 index 0000000..d495fe4 --- /dev/null +++ b/src/bench_wiring.rs @@ -0,0 +1,54 @@ +use criterion::{black_box, Criterion}; +use tokio::runtime::Runtime; +use wiring::prelude::{Unwire, Unwiring, Wire, Wiring}; +use zstd::zstd_safe::WriteBuf; + +pub fn bench<'a, T>(name: &'static str, c: &mut Criterion, data: &'a T) +where + &'a T: Wiring, + T: Unwiring + PartialEq, +{ + async fn wire_data(mut wire: W, data: T) { + (&mut wire).wire(data).await.unwrap(); + } + + let rt = Runtime::new().unwrap(); + const BUFFER_LEN: usize = 50_000_000; + + let mut group = c.benchmark_group(format!("{}/wiring", name)); + + let mut wire: Vec = Vec::with_capacity(BUFFER_LEN); + + group.bench_function("serialize", |b| { + b.to_async(Runtime::new().unwrap()).iter_batched( + || wire.clone(), + |w| wire_data(black_box(w), black_box(data)), + criterion::BatchSize::SmallInput, + ); + }); + + rt.block_on(async { + (&mut wire).wire(data).await.unwrap(); + }); + + let mut unwire = std::io::Cursor::new(wire); + + group.bench_function("deserialize", |b| { + b.to_async(Runtime::new().unwrap()).iter_batched( + || unwire.clone(), + |w| async move { + black_box(w).unwire::().await.unwrap(); + }, + criterion::BatchSize::SmallInput, + ); + }); + + crate::bench_size(name, "wiring", unwire.as_slice()); + + rt.block_on(async { + let unwired = unwire.unwire::().await.unwrap(); + assert!(&unwired == data); + }); + + group.finish(); +} diff --git a/src/datasets/log/mod.rs b/src/datasets/log/mod.rs index faa2ea7..b452e4c 100644 --- a/src/datasets/log/mod.rs +++ b/src/datasets/log/mod.rs @@ -21,6 +21,8 @@ use nanoserde::{DeBin, SerBin}; use rand::Rng; #[cfg(feature = "rkyv")] use rkyv::Archived; +#[cfg(feature = "wiring")] +use wiring::prelude::{Unwiring, Wiring}; #[cfg(feature = "capnp")] use crate::bench_capnp; @@ -59,6 +61,7 @@ use crate::Generate; #[cfg_attr(feature = "speedy", derive(speedy::Readable, speedy::Writable))] #[cfg_attr(feature = "alkahest", derive(alkahest::Schema))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring))] pub struct Address { #[cfg_attr(feature = "bilrost", bilrost(encoding(varint)))] pub x0: u8, @@ -172,6 +175,7 @@ impl alkahest::Pack
for Address { #[cfg_attr(feature = "speedy", derive(speedy::Readable, speedy::Writable))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring))] pub struct Log { pub address: Address, pub identity: String, @@ -397,6 +401,7 @@ impl alkahest::Pack for &'_ Log { #[cfg_attr(feature = "speedy", derive(speedy::Readable, speedy::Writable))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring))] pub struct Logs { #[cfg_attr(feature = "bilrost", bilrost(encoding(packed)))] pub logs: Vec, diff --git a/src/datasets/mesh/mod.rs b/src/datasets/mesh/mod.rs index 8922647..007ba60 100644 --- a/src/datasets/mesh/mod.rs +++ b/src/datasets/mesh/mod.rs @@ -19,6 +19,8 @@ use nanoserde::{DeBin, SerBin}; use rand::Rng; #[cfg(feature = "rkyv")] use rkyv::Archived; +#[cfg(feature = "wiring")] +use wiring::prelude::{Unwiring, Wiring}; #[cfg(feature = "capnp")] use crate::bench_capnp; @@ -57,6 +59,7 @@ use crate::Generate; #[cfg_attr(feature = "alkahest", derive(alkahest::Schema))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring))] pub struct Vector3 { pub x: f32, pub y: f32, @@ -161,6 +164,7 @@ impl alkahest::Pack for Vector3 { #[cfg_attr(feature = "alkahest", derive(alkahest::Schema))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring))] pub struct Triangle { pub v0: Vector3, pub v1: Vector3, @@ -276,6 +280,7 @@ impl alkahest::Pack for &'_ Triangle { #[cfg_attr(feature = "speedy", derive(speedy::Readable, speedy::Writable))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring))] pub struct Mesh { #[cfg_attr(feature = "bilrost", bilrost(encoding(packed)))] pub triangles: Vec, diff --git a/src/datasets/minecraft_savedata/mod.rs b/src/datasets/minecraft_savedata/mod.rs index 962775f..7014151 100644 --- a/src/datasets/minecraft_savedata/mod.rs +++ b/src/datasets/minecraft_savedata/mod.rs @@ -23,6 +23,8 @@ use nanoserde::{DeBin, SerBin}; use rand::Rng; #[cfg(feature = "rkyv")] use rkyv::Archived; +#[cfg(feature = "wiring")] +use wiring::prelude::{Unwiring, Wiring}; #[cfg(feature = "capnp")] use crate::bench_capnp; @@ -61,6 +63,7 @@ use crate::{generate_vec, Generate}; #[cfg_attr(feature = "alkahest", derive(alkahest::Schema))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring), tag(u8))] #[repr(u8)] pub enum GameType { #[cfg_attr(feature = "bilrost", bilrost(0))] @@ -177,6 +180,7 @@ impl alkahest::Pack for GameType { #[cfg_attr(feature = "speedy", derive(speedy::Readable, speedy::Writable))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring))] pub struct Item { #[cfg_attr(feature = "bilrost", bilrost(encoding(varint)))] pub count: i8, @@ -314,6 +318,7 @@ impl alkahest::Pack for &'_ Item { #[cfg_attr(feature = "alkahest", derive(alkahest::Schema))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring))] pub struct Abilities { pub walk_speed: f32, pub fly_speed: f32, @@ -448,6 +453,7 @@ impl alkahest::Pack for Abilities { #[cfg_attr(feature = "speedy", derive(speedy::Readable, speedy::Writable))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring))] pub struct Entity { pub id: String, pub pos: (f64, f64, f64), @@ -756,6 +762,7 @@ impl alkahest::Pack for &'_ Entity { #[cfg_attr(feature = "speedy", derive(speedy::Readable, speedy::Writable))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring))] pub struct RecipeBook { #[cfg_attr(feature = "bilrost", bilrost(encoding(packed)))] pub recipes: Vec, @@ -982,6 +989,7 @@ impl alkahest::Pack for &'_ RecipeBook { #[cfg_attr(feature = "speedy", derive(speedy::Readable, speedy::Writable))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring))] pub struct Player { pub game_type: GameType, pub previous_game_type: GameType, @@ -1469,6 +1477,7 @@ impl alkahest::Pack for &'_ Player { #[cfg_attr(feature = "speedy", derive(speedy::Readable, speedy::Writable))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring))] pub struct Players { pub players: Vec, } diff --git a/src/datasets/mk48/mod.rs b/src/datasets/mk48/mod.rs index bc78061..b23a2dc 100644 --- a/src/datasets/mk48/mod.rs +++ b/src/datasets/mk48/mod.rs @@ -25,6 +25,8 @@ use nanoserde::{DeBin, SerBin}; use rand::Rng; #[cfg(feature = "rkyv")] use rkyv::Archived; +#[cfg(feature = "wiring")] +use wiring::prelude::{Unwiring, Wiring}; #[cfg(feature = "capnp")] use crate::bench_capnp; @@ -63,6 +65,7 @@ use crate::{generate_vec, Generate}; #[cfg_attr(feature = "alkahest", derive(alkahest::Schema))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring), tag(u8))] #[repr(u8)] pub enum EntityType { #[cfg_attr(feature = "bilrost", bilrost(0))] @@ -313,6 +316,7 @@ fn generate_velocity(rng: &mut impl Rng) -> i16 { #[cfg_attr(feature = "alkahest", derive(alkahest::Schema))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring))] pub struct Transform { pub altitude: i8, pub angle: u16, @@ -442,6 +446,7 @@ impl alkahest::Pack for Transform { #[cfg_attr(feature = "alkahest", derive(alkahest::Schema))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring))] pub struct Guidance { pub angle: u16, pub submerge: bool, @@ -544,6 +549,7 @@ impl alkahest::Pack for Guidance { #[cfg_attr(feature = "speedy", derive(speedy::Readable, speedy::Writable))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring))] pub struct Contact { pub damage: u8, pub entity_id: u32, @@ -769,6 +775,7 @@ impl alkahest::Pack for &'_ Contact { #[cfg_attr(feature = "speedy", derive(speedy::Readable, speedy::Writable))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring))] pub struct TerrainUpdate { chunk_id: (i8, i8), data: Vec, @@ -909,6 +916,7 @@ impl alkahest::Pack for &'_ TerrainUpdate { #[cfg_attr(feature = "speedy", derive(speedy::Readable, speedy::Writable))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring))] pub struct Update { pub contacts: Vec, pub score: u32, @@ -1077,6 +1085,7 @@ impl alkahest::Pack for &'_ Update { #[cfg_attr(feature = "speedy", derive(speedy::Readable, speedy::Writable))] #[cfg_attr(feature = "savefile", derive(savefile_derive::Savefile))] #[cfg_attr(feature = "nanoserde", derive(nanoserde::SerBin, nanoserde::DeBin))] +#[cfg_attr(feature = "wiring", derive(Wiring, Unwiring))] pub struct Updates { pub updates: Vec, } diff --git a/src/lib.rs b/src/lib.rs index 4564bce..83579a0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -58,6 +58,8 @@ pub mod bench_serde_json; pub mod bench_simd_json; #[cfg(feature = "speedy")] pub mod bench_speedy; +#[cfg(feature = "wiring")] +pub mod bench_wiring; pub mod datasets; use core::{mem, ops};