use bytes::Bytes;
use criterion::{criterion_group, criterion_main, Criterion};
use http_body_util::Full;
use hyper::service::service_fn;
use hyper_util::rt::TokioIo;
use std::convert::Infallible;
use std::net::SocketAddr;
use std::time::Duration;
use tokio::net::TcpListener;
async fn spawn_echo_server() -> SocketAddr {
let listener = TcpListener::bind("127.0.0.1:0")
.await
.expect("facade bench bind");
let addr = listener.local_addr().expect("facade bench local addr");
tokio::spawn(async move {
loop {
let Ok((stream, _)) = listener.accept().await else {
break;
};
tokio::spawn(async move {
let _ = hyper::server::conn::http1::Builder::new()
.serve_connection(
TokioIo::new(stream),
service_fn(|_req: hyper::Request<hyper::body::Incoming>| async {
Ok::<_, Infallible>(hyper::Response::new(Full::new(
Bytes::from_static(b"OK"),
)))
}),
)
.await;
});
}
});
addr
}
fn bench_facade_get_overhead(c: &mut Criterion) {
let rt = tokio::runtime::Runtime::new().expect("facade overhead rt");
let addr = rt.block_on(spawn_echo_server());
let url = format!("http://{addr}/");
let mut group = c.benchmark_group("facade_overhead");
group.sample_size(10);
group.measurement_time(Duration::from_secs(5));
{
let u = url.clone();
group.bench_function("facade_get", |b| {
b.to_async(&rt).iter(|| {
let u = u.as_str();
async move {
let resp = oxihttp::get(u).await.expect("facade GET");
std::hint::black_box(resp);
}
});
});
}
{
let u = url.clone();
group.bench_function("direct_client_get", |b| {
b.to_async(&rt).iter(|| {
let u = u.as_str();
async move {
let client = oxihttp::Client::builder()
.build()
.expect("direct client build");
let resp = client
.get(u)
.expect("GET")
.send()
.await
.expect("direct GET");
std::hint::black_box(resp);
}
});
});
}
group.finish();
}
fn bench_client_construction(c: &mut Criterion) {
let mut group = c.benchmark_group("client_construction");
group.bench_function("builder_build", |b| {
b.iter(|| std::hint::black_box(oxihttp::Client::builder().build().expect("client build")));
});
group.finish();
}
criterion_group!(
facade_benches,
bench_facade_get_overhead,
bench_client_construction,
);
criterion_main!(facade_benches);