Skip to content

Commit

Permalink
Merge pull request #162 from Totodore/feat-engineio-bench
Browse files Browse the repository at this point in the history
Optimize `engineio` packets processing
  • Loading branch information
Totodore authored Nov 25, 2023
2 parents bb2cea1 + 0091c6b commit 68a5424
Show file tree
Hide file tree
Showing 11 changed files with 176 additions and 106 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 16 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ resolver = "2"
[workspace.dependencies]
futures = "0.3.27"
tokio = "1.34.0"
tokio-tungstenite = "0.20.1"
serde = { version = "1.0.193", features = ["derive"] }
serde_json = "1.0.108"
tower = { version = "0.4.13", default-features = false }
Expand All @@ -14,12 +15,6 @@ thiserror = "1.0.40"
tracing = "0.1.37"
itoa = "1.0.9"

tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
hyper = "0.14.25"
axum = "0.6.20"
warp = "0.3.6"
salvo = { version = "0.58.5", features = ["tower-compat"] }

# Hyper v0.1
http-body-v1 = { package = "http-body", version = "1.0.0-rc.2" }
hyper-v1 = { package = "hyper", version = "1.0.0-rc.4", features = [
Expand All @@ -28,6 +23,21 @@ hyper-v1 = { package = "hyper", version = "1.0.0-rc.4", features = [
"http2",
] }

# Dev deps
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
criterion = { version = "0.5.1", features = ["html_reports"] }
hyper = { version = "0.14.25", features = [
"http1",
"http2",
"server",
"stream",
"runtime",
"client",
] }
axum = "0.6.20"
warp = "0.3.6"
salvo = { version = "0.58.5", features = ["tower-compat"] }

[workspace.package]
version = "0.7.2"
edition = "2021"
Expand Down
21 changes: 12 additions & 9 deletions engineioxide/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ thiserror.workspace = true
tokio = { workspace = true, features = ["rt", "time"] }
tower.workspace = true
hyper.workspace = true
tokio-tungstenite.workspace = true

base64 = "0.21.0"
bytes = "1.4.0"
pin-project = "1.0.12"
tokio-tungstenite = "0.20.1"
rand = "0.8.5"

# Tracing
Expand All @@ -48,14 +48,7 @@ http-body-v1 = { workspace = true, optional = true }
[dev-dependencies]
tokio = { workspace = true, features = ["macros", "parking_lot"] }
tracing-subscriber.workspace = true
hyper = { workspace = true, features = [
"http1",
"http2",
"server",
"stream",
"runtime",
"client",
] }
criterion.workspace = true
warp.workspace = true
axum.workspace = true
salvo.workspace = true
Expand All @@ -65,3 +58,13 @@ v3 = ["memchr", "unicode-segmentation"]
test-utils = []
tracing = ["dep:tracing"]
hyper-v1 = ["dep:hyper-v1", "dep:http-body-v1"]

[[bench]]
name = "packet_encode"
path = "benches/packet_encode.rs"
harness = false

[[bench]]
name = "packet_decode"
path = "benches/packet_decode.rs"
harness = false
32 changes: 32 additions & 0 deletions engineioxide/benches/packet_decode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use engineioxide::Packet;

fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("Decode packet ping/pong", |b| {
let packet: String = Packet::Ping.try_into().unwrap();
b.iter(|| Packet::try_from(packet.as_str()).unwrap())
});
c.bench_function("Decode packet ping/pong upgrade", |b| {
let packet: String = Packet::PingUpgrade.try_into().unwrap();
b.iter(|| Packet::try_from(packet.as_str()).unwrap())
});
c.bench_function("Decode packet message", |b| {
let packet: String = Packet::Message(black_box("Hello").to_string())
.try_into()
.unwrap();
b.iter(|| Packet::try_from(packet.as_str()).unwrap())
});
c.bench_function("Decode packet noop", |b| {
let packet: String = Packet::Noop.try_into().unwrap();
b.iter(|| Packet::try_from(packet.as_str()).unwrap())
});
c.bench_function("Decode packet binary b64", |b| {
let packet: String = Packet::Binary(black_box(vec![0x00, 0x01, 0x02, 0x03, 0x04, 0x05]))
.try_into()
.unwrap();
b.iter(|| Packet::try_from(packet.clone()).unwrap())
});
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
36 changes: 36 additions & 0 deletions engineioxide/benches/packet_encode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use engineioxide::{config::EngineIoConfig, sid::Sid, OpenPacket, Packet, TransportType};

fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("Encode packet open", |b| {
let packet = Packet::Open(OpenPacket::new(
black_box(TransportType::Polling),
black_box(Sid::ZERO),
&EngineIoConfig::default(),
));
b.iter(|| TryInto::<String>::try_into(packet.clone()))
});
c.bench_function("Encode packet ping/pong", |b| {
let packet = Packet::Ping;
b.iter(|| TryInto::<String>::try_into(packet.clone()))
});
c.bench_function("Encode packet ping/pong upgrade", |b| {
let packet = Packet::PingUpgrade;
b.iter(|| TryInto::<String>::try_into(packet.clone()))
});
c.bench_function("Encode packet message", |b| {
let packet = Packet::Message(black_box("Hello").to_string());
b.iter(|| TryInto::<String>::try_into(packet.clone()))
});
c.bench_function("Encode packet noop", |b| {
let packet = Packet::Noop;
b.iter(|| TryInto::<String>::try_into(packet.clone()))
});
c.bench_function("Encode packet binary b64", |b| {
let packet = Packet::Binary(black_box(vec![0x00, 0x01, 0x02, 0x03, 0x04, 0x05]));
b.iter(|| TryInto::<String>::try_into(packet.clone()))
});
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
12 changes: 8 additions & 4 deletions engineioxide/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ pub enum Error {

#[error("Invalid packet length")]
InvalidPacketLength,
#[error("Invalid packet type")]
InvalidPacketType(Option<char>),
}

/// Convert an error into an http response
Expand All @@ -64,10 +66,12 @@ impl<B> From<Error> for Response<ResponseBody<B>> {
.status(code)
.body(ResponseBody::empty_response())
.unwrap(),
Error::BadPacket(_) => Response::builder()
.status(400)
.body(ResponseBody::empty_response())
.unwrap(),
Error::BadPacket(_) | Error::InvalidPacketLength | Error::InvalidPacketType(_) => {
Response::builder()
.status(400)
.body(ResponseBody::empty_response())
.unwrap()
}
Error::PayloadTooLarge => Response::builder()
.status(413)
.body(ResponseBody::empty_response())
Expand Down
3 changes: 3 additions & 0 deletions engineioxide/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
pub use service::{ProtocolVersion, TransportType};
pub use socket::{DisconnectReason, Socket};

#[cfg(feature = "test-utils")]
pub use packet::*;

pub mod config;
pub mod handler;
pub mod layer;
Expand Down
Loading

0 comments on commit 68a5424

Please sign in to comment.