-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
311 additions
and
85 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
//! Benchmarks for network protocols [Quic/TCP] | ||
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; | ||
use pprof::criterion::{Output, PProfProfiler}; | ||
use proto::{ | ||
connection::{ | ||
protocols::{ | ||
quic::Quic, tcp::Tcp, Listener, Protocol, Receiver, Sender, UnfinalizedConnection, | ||
}, | ||
Bytes, | ||
}, | ||
message::{Broadcast, Message}, | ||
}; | ||
use tokio::{join, runtime::Runtime, spawn}; | ||
|
||
/// Transfer a message `raw_message` from `conn1` to `conn2.` This is the primary | ||
/// function used for testing network protocol speed. | ||
async fn transfer<Proto: Protocol>( | ||
conn1: (Proto::Sender, Proto::Receiver), | ||
conn2: (Proto::Sender, Proto::Receiver), | ||
raw_message: Bytes, | ||
) { | ||
// Send from the first connection | ||
let conn1_jh = spawn(async move { | ||
conn1 | ||
.0 | ||
.send_message_raw(raw_message.clone()) | ||
.await | ||
.expect("failed to send message"); | ||
}); | ||
|
||
// Receive from the second connection | ||
let conn2_jh = spawn(async move { | ||
conn2 | ||
.1 | ||
.recv_message_raw() | ||
.await | ||
.expect("failed to receive message"); | ||
}); | ||
|
||
// Wait for both to finish | ||
let _ = join!(conn1_jh, conn2_jh); | ||
} | ||
|
||
/// Set up our protocol benchmarks, including async runtime, given the message size | ||
/// to test. | ||
fn set_up_bench<Proto: Protocol>( | ||
message_size: usize, | ||
) -> ( | ||
Runtime, | ||
(Proto::Sender, Proto::Receiver), | ||
(Proto::Sender, Proto::Receiver), | ||
Bytes, | ||
) { | ||
// Create new tokio runtime | ||
let benchmark_runtime = tokio::runtime::Runtime::new().expect("failed to create Tokio runtime"); | ||
|
||
// Set up our protocol under test | ||
let (conn1, conn2, message) = benchmark_runtime.block_on(async move { | ||
// Find random, open port to use | ||
let port = portpicker::pick_unused_port().expect("no ports available"); | ||
|
||
// Create listener, bind to port | ||
let listener = Proto::bind(&format!("127.0.0.1:{}", port), None, None) | ||
.await | ||
.expect("failed to listen on port"); | ||
|
||
// Spawn future that resolves to our inbound connection | ||
let listener_jh = spawn(async move { | ||
// Accept connection | ||
let unfinalized_connection = | ||
listener.accept().await.expect("failed to open connection"); | ||
|
||
// Finalize the connection | ||
unfinalized_connection | ||
.finalize() | ||
.await | ||
.expect("failed to finalize connection") | ||
}); | ||
|
||
// Attempt to connect | ||
let conn1 = Proto::connect(&format!("127.0.0.1:{}", port)) | ||
.await | ||
.expect("failed to connect to listener"); | ||
|
||
// Wait for listener to resolve | ||
let conn2 = listener_jh.await.expect("failed to join listener task"); | ||
|
||
// Create message of particular size | ||
let message = Bytes::from( | ||
Message::Broadcast(Broadcast { | ||
topics: vec![], | ||
message: vec![0; message_size], | ||
}) | ||
.serialize() | ||
.expect("failed to serialize message"), | ||
); | ||
|
||
(conn1, conn2, message) | ||
}); | ||
|
||
(benchmark_runtime, conn1, conn2, message) | ||
} | ||
|
||
/// Bench the `QUIC` protocol implementation | ||
fn bench_quic(c: &mut Criterion) { | ||
static KB: usize = 1024; | ||
static MB: usize = 1024 * 1024; | ||
let mut group = c.benchmark_group("quic_transfer"); | ||
// The message sizes we want to test | ||
for size in [100, 1 * KB, 100 * KB, 10 * MB, 100 * MB].iter() { | ||
// Set up our bench | ||
let (runtime, conn1, conn2, message) = set_up_bench::<Quic>(*size); | ||
|
||
// Run with variable throughput | ||
group.throughput(Throughput::Bytes(*size as u64)); | ||
group.bench_function(BenchmarkId::from_parameter(size), |b| { | ||
b.to_async(&runtime).iter(|| { | ||
transfer::<Quic>( | ||
black_box(conn1.clone()), | ||
black_box(conn2.clone()), | ||
black_box(message.clone()), | ||
) | ||
}); | ||
}); | ||
} | ||
|
||
group.finish(); | ||
} | ||
|
||
/// Bench the `TCP` protocol implementation | ||
fn bench_tcp(c: &mut Criterion) { | ||
static KB: usize = 1024; | ||
static MB: usize = 1024 * 1024; | ||
let mut group = c.benchmark_group("tcp_transfer"); | ||
// The message sizes we want to test | ||
for size in [100, 1 * KB, 100 * KB, 10 * MB, 100 * MB].iter() { | ||
// Set up our bench | ||
let (runtime, conn1, conn2, message) = set_up_bench::<Tcp>(*size); | ||
|
||
// Run with variable throughput | ||
group.throughput(Throughput::Bytes(*size as u64)); | ||
group.bench_function(BenchmarkId::from_parameter(size), |b| { | ||
b.to_async(&runtime).iter(|| { | ||
transfer::<Tcp>( | ||
black_box(conn1.clone()), | ||
black_box(conn2.clone()), | ||
black_box(message.clone()), | ||
) | ||
}); | ||
}); | ||
} | ||
|
||
group.finish(); | ||
} | ||
|
||
// Set up the benchmnark with the optional flamegraph profiler | ||
criterion_group! { | ||
name = benches; | ||
config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None))); | ||
targets = bench_quic, bench_tcp | ||
} | ||
|
||
criterion_main!(benches); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.