Skip to content

Commit

Permalink
Add naive benchmark (googleforgames#321)
Browse files Browse the repository at this point in the history
* Add naive benchmark

* Update build/README.md

Co-authored-by: Mark Mandel <[email protected]>

Co-authored-by: Mark Mandel <[email protected]>
  • Loading branch information
XAMPPRocky and markmandel authored Jul 23, 2021
1 parent 36be5eb commit 64c25fc
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ categories = ["game-development", "network-programming"]
edition = "2018"
exclude = ["docs", "build", "examples", "image"]

[[bench]]
name = "throughput"
harness = false
test = true

[dependencies]
# Local
quilkin-macros = { version = "0.2.0-dev", path = "./macros" }
Expand Down Expand Up @@ -67,6 +72,8 @@ thiserror = "1.0.25"
[dev-dependencies]
reqwest = "0.11.0"
regex = "1.3.9"
criterion = { version = "0.3", features = ["html_reports"] }
once_cell = "1.8.0"

[build-dependencies]
tonic-build = { version = "0.5.1", default_features = false, features = ["transport", "prost"] }
Expand Down
102 changes: 102 additions & 0 deletions benches/throughput.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
use std::net::UdpSocket;

use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use once_cell::sync::Lazy;

const MESSAGE_SIZE: usize = 0xffff;
const DEFAULT_MESSAGE: [u8; 0xffff] = [0xff; 0xffff];
const BENCH_LOOP_ADDR: &str = "127.0.0.1:8002";
const FEEDBACK_LOOP_ADDR: &str = "127.0.0.1:8001";
const QUILKIN_ADDR: &str = "127.0.0.1:8000";
const NUMBER_OF_PACKETS: usize = 10_000;

const PACKETS: &[&[u8]] = &[
// Half IPv4 MTU.
&[0xffu8; 254],
// IPv4 MTU.
&[0xffu8; 508],
// Ethernet MTU.
&[0xffu8; 1500],
];

static SERVER_INIT: Lazy<()> = Lazy::new(|| {
std::thread::spawn(|| {
let runtime = tokio::runtime::Runtime::new().unwrap();
let config = quilkin::config::Builder::empty()
.with_port(8000)
.with_static(
vec![],
vec![quilkin::config::EndPoint::new(
FEEDBACK_LOOP_ADDR.parse().unwrap(),
)],
)
.build();
let server = quilkin::proxy::Builder::from(std::sync::Arc::new(config))
.validate()
.unwrap()
.build();

runtime.block_on(async move {
let (_shutdown_tx, shutdown_rx) = tokio::sync::watch::channel::<()>(());
server.run(shutdown_rx).await.unwrap();
});
});
});

static FEEDBACK_LOOP: Lazy<()> = Lazy::new(|| {
std::thread::spawn(|| {
let socket = UdpSocket::bind(FEEDBACK_LOOP_ADDR).unwrap();

loop {
let mut packet = [0; MESSAGE_SIZE];
let (_, addr) = socket.recv_from(&mut packet).unwrap();
let length = packet
.iter()
.position(|&x| x == 0)
.unwrap_or_else(|| packet.len());
let packet = &packet[..length];
assert_eq!(packet, &DEFAULT_MESSAGE[..length]);
socket.send_to(packet, addr).unwrap();
}
});
});

fn criterion_benchmark(c: &mut Criterion) {
Lazy::force(&FEEDBACK_LOOP);
Lazy::force(&SERVER_INIT);
// Sleep to give the servers some time to warm-up.
std::thread::sleep(std::time::Duration::from_millis(500));
let socket = UdpSocket::bind(BENCH_LOOP_ADDR).unwrap();
let mut packet = [0; MESSAGE_SIZE];

let mut group = c.benchmark_group("throughput");
for message in PACKETS {
group.sample_size(NUMBER_OF_PACKETS);
group.sampling_mode(criterion::SamplingMode::Flat);
group.throughput(criterion::Throughput::Bytes(message.len() as u64));
group.bench_with_input(
BenchmarkId::new("direct", format!("{} bytes", message.len())),
&message,
|b, message| {
b.iter(|| {
socket.send_to(message, FEEDBACK_LOOP_ADDR).unwrap();
socket.recv_from(&mut packet).unwrap();
})
},
);
group.bench_with_input(
BenchmarkId::new("quilkin", format!("{} bytes", message.len())),
&message,
|b, message| {
b.iter(|| {
socket.send_to(message, QUILKIN_ADDR).unwrap();
socket.recv_from(&mut packet).unwrap();
})
},
);
}
group.finish();
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
6 changes: 6 additions & 0 deletions build/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ To run our external documentation tests:

`cargo +nightly test --doc`

To run our benchmarks:

`cargo bench`

We use [criterion](https://github.com/bheisler/criterion.rs) for benchmarking. You can find visual reports under `./target/criterion`.

To test dependency licences and security advisories:

`cargo deny check`
Expand Down

0 comments on commit 64c25fc

Please sign in to comment.