use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; criterion_group!(benches, benchmark); criterion_main!(benches); fn benchmark(c: &mut Criterion) { let mut rt = tokio::runtime::Runtime::new().unwrap(); let sizes = [1, 10, 100, 1000]; let mut group = c.benchmark_group("futures/request-response"); for size in sizes.iter() { let id = BenchmarkId::from_parameter(size); group.bench_with_input(id, size, |b, &size| b.iter(|| { rt.block_on(futures_request_response(size)) })); } group.finish(); let mut group = c.benchmark_group("tokio/request-response"); for size in sizes.iter() { let id = BenchmarkId::from_parameter(size); group.bench_with_input(id, size, |b, &size| b.iter(|| { rt.block_on(tokio_request_response(size)) })); } group.finish(); let mut group = c.benchmark_group("scambio/request-response"); for size in sizes.iter() { let id = BenchmarkId::from_parameter(size); group.bench_with_input(id, size, |b, &size| b.iter(|| { rt.block_on(scambio_request_response(size)) })); } group.finish(); let mut group = c.benchmark_group("futures/oneshot"); for size in sizes.iter() { let id = BenchmarkId::from_parameter(size); group.bench_with_input(id, size, |b, &size| b.iter(|| { rt.block_on(futures_oneshot(size)) })); } group.finish(); let mut group = c.benchmark_group("tokio/oneshot"); for size in sizes.iter() { let id = BenchmarkId::from_parameter(size); group.bench_with_input(id, size, |b, &size| b.iter(|| { rt.block_on(tokio_oneshot(size)) })); } group.finish(); let mut group = c.benchmark_group("scambio/oneshot"); for size in sizes.iter() { let id = BenchmarkId::from_parameter(size); group.bench_with_input(id, size, |b, &size| b.iter(|| { rt.block_on(scambio_oneshot(size)) })); } group.finish() } async fn futures_request_response(num: usize) { use futures::{channel::mpsc, prelude::*}; let (mut atx, mut arx) = mpsc::channel::(1); let (mut btx, mut brx) = mpsc::channel::(1); let client = tokio::spawn(async move { for i in 0 .. num { atx.send(i).await.unwrap(); assert_eq!(i, brx.next().await.unwrap()) } }); let server = tokio::spawn(async move { while let Some(i) = arx.next().await { btx.send(i).await.unwrap() } }); client.await.unwrap(); server.await.unwrap() } async fn tokio_request_response(num: usize) { use tokio::sync::mpsc; let (mut atx, mut arx) = mpsc::channel::(1); let (mut btx, mut brx) = mpsc::channel::(1); let client = tokio::spawn(async move { for i in 0 .. num { atx.send(i).await.unwrap(); assert_eq!(i, brx.recv().await.unwrap()) } }); let server = tokio::spawn(async move { while let Some(i) = arx.recv().await { btx.send(i).await.unwrap() } }); client.await.unwrap(); server.await.unwrap() } async fn scambio_request_response(num: usize) { let (mut a, mut b) = scambio::exchange(); let client = tokio::spawn(async move { for i in 0 .. num { a.send(i).await.unwrap(); assert_eq!(i, a.receive().await.unwrap()) } }); let server = tokio::spawn(async move { while let Some(i) = b.receive().await { b.send(i).await.unwrap() } }); client.await.unwrap(); server.await.unwrap() } async fn futures_oneshot(num: usize) { use futures::channel::oneshot; for _ in 0 .. num { let (tx, rx) = oneshot::channel(); tx.send(1u8).unwrap(); assert_eq!(1u8, rx.await.unwrap()) } } async fn tokio_oneshot(num: usize) { use tokio::sync::oneshot; for _ in 0 .. num { let (tx, rx) = oneshot::channel(); tx.send(1u8).unwrap(); assert_eq!(1u8, rx.await.unwrap()) } } async fn scambio_oneshot(num: usize) { enum Void {} for _ in 0 .. num { let (mut a, mut b) = scambio::exchange::(); a.send_now(1u8).unwrap(); assert_eq!(1u8, b.receive().await.unwrap()) } }