resurrect benches

Because these require nightly, CI isn't configured to fail if they're
broken. And they have been broken since the conversion to hyper 1.x.
This commit is contained in:
Scott Lamb 2025-03-06 21:32:01 -08:00
parent e204fe0864
commit 3cc9603ff3
3 changed files with 106 additions and 63 deletions

View File

@ -659,10 +659,12 @@ mod bench {
let data = include_bytes!("testdata/video_sample_index.bin"); let data = include_bytes!("testdata/video_sample_index.bin");
b.bytes = data.len() as u64; b.bytes = data.len() as u64;
b.iter(|| { b.iter(|| {
let mut it = SampleIndexIterator::default(); for _i in 0..100 {
while it.next(data).unwrap() {} let mut it = SampleIndexIterator::default();
assert_eq!(30104460, it.pos); while it.next(data).unwrap() {}
assert_eq!(5399985, it.start_90k); assert_eq!(30104460, it.pos);
assert_eq!(5399985, it.start_90k);
}
}); });
} }
} }

View File

@ -2973,13 +2973,16 @@ mod tests {
mod bench { mod bench {
extern crate test; extern crate test;
use std::convert::Infallible;
use std::net::SocketAddr;
use super::tests::create_mp4_from_db; use super::tests::create_mp4_from_db;
use base::clock::RealClocks; use base::clock::RealClocks;
use db::recording; use db::recording;
use db::testutil::{self, TestDb}; use db::testutil::{self, TestDb};
use futures::future;
use http_serve; use http_serve;
use hyper; use hyper;
use hyper::service::service_fn;
use url::Url; use url::Url;
/// An HTTP server for benchmarking. /// An HTTP server for benchmarking.
@ -3000,28 +3003,35 @@ mod bench {
testutil::add_dummy_recordings_to_db(&db.db, 60); testutil::add_dummy_recordings_to_db(&db.db, 60);
let mp4 = create_mp4_from_db(&db, 0, 0, false); let mp4 = create_mp4_from_db(&db, 0, 0, false);
let p = mp4.0.initial_sample_byte_pos; let p = mp4.0.initial_sample_byte_pos;
let make_svc = hyper::service::make_service_fn(move |_conn| { let addr: SocketAddr = ([127, 0, 0, 1], 0).into();
future::ok::<_, std::convert::Infallible>(hyper::service::service_fn({ let listener = std::net::TcpListener::bind(addr).unwrap();
listener.set_nonblocking(true).unwrap();
let addr = listener.local_addr().unwrap(); // resolve port 0 to a real ephemeral port number.
let srv = async move {
let listener = tokio::net::TcpListener::from_std(listener).unwrap();
loop {
let (conn, _remote_addr) = listener.accept().await.unwrap();
conn.set_nodelay(true).unwrap();
let io = hyper_util::rt::TokioIo::new(conn);
let mp4 = mp4.clone(); let mp4 = mp4.clone();
move |req| { let svc_fn = service_fn(move |req| {
future::ok::<hyper::Response<crate::body::Body>, hyper::Error>( futures::future::ok::<_, Infallible>(http_serve::serve(mp4.clone(), &req))
http_serve::serve(mp4.clone(), &req), });
) tokio::spawn(
} hyper::server::conn::http1::Builder::new().serve_connection(io, svc_fn),
})) );
}); }
let rt = tokio::runtime::Runtime::new().unwrap();
let srv = {
let _guard = rt.enter();
let addr = ([127, 0, 0, 1], 0).into();
hyper::server::Server::bind(&addr)
.tcp_nodelay(true)
.serve(make_svc)
}; };
let addr = srv.local_addr(); // resolve port 0 to a real ephemeral port number. std::thread::Builder::new()
::std::thread::spawn(move || { .name("bench-server".to_owned())
rt.block_on(srv).unwrap(); .spawn(move || {
}); let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();
rt.block_on(srv)
})
.unwrap();
BenchServer { BenchServer {
url: Url::parse(&format!("http://{}:{}/", addr.ip(), addr.port())).unwrap(), url: Url::parse(&format!("http://{}:{}/", addr.ip(), addr.port())).unwrap(),
generated_len: p, generated_len: p,
@ -3053,7 +3063,11 @@ mod bench {
db.with_recording_playback(segment.s.id, &mut |playback| { db.with_recording_playback(segment.s.id, &mut |playback| {
let v = segment.build_index(playback).unwrap(); // warm. let v = segment.build_index(playback).unwrap(); // warm.
b.bytes = v.len() as u64; // define the benchmark performance in terms of output bytes. b.bytes = v.len() as u64; // define the benchmark performance in terms of output bytes.
b.iter(|| segment.build_index(playback).unwrap()); b.iter(|| {
for _i in 0..100 {
segment.build_index(playback).unwrap();
}
});
Ok(()) Ok(())
}) })
.unwrap(); .unwrap();
@ -3067,17 +3081,25 @@ mod bench {
let p = server.generated_len; let p = server.generated_len;
b.bytes = p; b.bytes = p;
let client = reqwest::Client::new(); let client = reqwest::Client::new();
let rt = tokio::runtime::Runtime::new().unwrap(); let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();
let run = || { let run = || {
rt.block_on(async { rt.block_on(async {
let resp = client for _i in 0..100 {
.get(server.url.clone()) let mut resp = client
.header(reqwest::header::RANGE, format!("bytes=0-{}", p - 1)) .get(server.url.clone())
.send() .header(reqwest::header::RANGE, format!("bytes=0-{}", p - 1))
.await .send()
.unwrap(); .await
let b = resp.bytes().await.unwrap(); .unwrap();
assert_eq!(p, b.len() as u64); let mut size = 0u64;
while let Some(b) = resp.chunk().await.unwrap() {
size += u64::try_from(b.len()).unwrap();
}
assert_eq!(p, size);
}
}); });
}; };
run(); // warm. run(); // warm.
@ -3090,7 +3112,9 @@ mod bench {
let db = TestDb::new(RealClocks {}); let db = TestDb::new(RealClocks {});
testutil::add_dummy_recordings_to_db(&db.db, 60); testutil::add_dummy_recordings_to_db(&db.db, 60);
b.iter(|| { b.iter(|| {
create_mp4_from_db(&db, 0, 0, false); for _i in 0..100 {
create_mp4_from_db(&db, 0, 0, false);
}
}); });
} }
} }

View File

@ -782,8 +782,11 @@ mod bench {
extern crate test; extern crate test;
use db::testutil::{self, TestDb}; use db::testutil::{self, TestDb};
use hyper; use hyper::{self, service::service_fn};
use std::sync::{Arc, OnceLock}; use std::{
net::SocketAddr,
sync::{Arc, OnceLock},
};
use uuid::Uuid; use uuid::Uuid;
struct Server { struct Server {
@ -807,32 +810,41 @@ mod bench {
}) })
.unwrap(), .unwrap(),
); );
let make_svc = hyper::service::make_service_fn(move |_conn| { let addr: SocketAddr = ([127, 0, 0, 1], 0).into();
futures::future::ok::<_, std::convert::Infallible>(hyper::service::service_fn({ let listener = std::net::TcpListener::bind(addr).unwrap();
let s = Arc::clone(&service); listener.set_nonblocking(true).unwrap();
move |req| { let addr = listener.local_addr().unwrap(); // resolve port 0 to a real ephemeral port number.
Arc::clone(&s).serve( let srv = async move {
let listener = tokio::net::TcpListener::from_std(listener).unwrap();
loop {
let (conn, _remote_addr) = listener.accept().await.unwrap();
conn.set_nodelay(true).unwrap();
let io = hyper_util::rt::TokioIo::new(conn);
let service = Arc::clone(&service);
let svc_fn = service_fn(move |req| {
Arc::clone(&service).serve(
req, req,
super::accept::ConnData { super::accept::ConnData {
client_unix_uid: None, client_unix_uid: None,
client_addr: None, client_addr: None,
}, },
) )
} });
})) tokio::spawn(
}); hyper::server::conn::http1::Builder::new().serve_connection(io, svc_fn),
let rt = tokio::runtime::Runtime::new().unwrap(); );
let srv = { }
let _guard = rt.enter();
let addr = ([127, 0, 0, 1], 0).into();
hyper::server::Server::bind(&addr)
.tcp_nodelay(true)
.serve(make_svc)
}; };
let addr = srv.local_addr(); // resolve port 0 to a real ephemeral port number. std::thread::Builder::new()
::std::thread::spawn(move || { .name("bench-server".to_owned())
rt.block_on(srv).unwrap(); .spawn(move || {
}); let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();
rt.block_on(srv)
})
.unwrap();
Server { Server {
base_url: format!("http://{}:{}", addr.ip(), addr.port()), base_url: format!("http://{}:{}", addr.ip(), addr.port()),
test_camera_uuid, test_camera_uuid,
@ -852,13 +864,18 @@ mod bench {
)) ))
.unwrap(); .unwrap();
let client = reqwest::Client::new(); let client = reqwest::Client::new();
let rt = tokio::runtime::Runtime::new().unwrap(); let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();
let f = || { let f = || {
rt.block_on(async { for _i in 0..100 {
let resp = client.get(url.clone()).send().await.unwrap(); rt.block_on(async {
assert_eq!(resp.status(), reqwest::StatusCode::OK); let resp = client.get(url.clone()).send().await.unwrap();
let _b = resp.bytes().await.unwrap(); assert_eq!(resp.status(), reqwest::StatusCode::OK);
}); let _b = resp.bytes().await.unwrap();
});
}
}; };
f(); // warm. f(); // warm.
b.iter(f); b.iter(f);