pub use tokio;
pub trait Runtime {
fn block_on<F>(&self, future: F) -> F::Output
where
F: blueprint_std::future::Future;
}
#[derive(Debug, Clone, Copy)]
pub struct TokioRuntime;
impl Runtime for TokioRuntime {
fn block_on<F>(&self, future: F) -> F::Output
where
F: blueprint_std::future::Future,
{
let rt = tokio::runtime::Handle::current();
rt.block_on(future)
}
}
#[derive(Debug)]
#[allow(dead_code)]
pub struct Bencher<R> {
runtime: R,
started_at: blueprint_std::time::Instant,
cores: usize,
}
#[derive(Debug, Clone)]
pub struct BenchmarkSummary {
pub name: String,
pub job_id: u8,
pub elapsed: blueprint_std::time::Duration,
pub cores: usize,
pub ram_usage: u64,
}
impl<R: Runtime> Bencher<R> {
pub fn new(threads: usize, runtime: R) -> Self {
Self {
runtime,
started_at: blueprint_std::time::Instant::now(),
cores: threads,
}
}
pub fn block_on<F>(&self, future: F) -> F::Output
where
F: blueprint_std::future::Future,
{
self.runtime.block_on(future)
}
#[cfg(feature = "std")] #[allow(clippy::needless_pass_by_value)]
pub fn stop<N: ToString>(&self, name: N, job_id: u8) -> BenchmarkSummary {
let pid = sysinfo::get_current_pid().expect("Failed to get current process ID");
let s = sysinfo::System::new_all();
let process = s
.process(pid)
.expect("Failed to get current process from the system");
let ram_usage = process.memory();
BenchmarkSummary {
name: name.to_string(),
job_id,
elapsed: self.started_at.elapsed(),
cores: self.cores,
ram_usage,
}
}
}
impl blueprint_std::fmt::Display for BenchmarkSummary {
#[allow(clippy::cast_precision_loss)]
fn fmt(&self, f: &mut blueprint_std::fmt::Formatter<'_>) -> blueprint_std::fmt::Result {
const KB: f32 = 1024.00;
const MB: f32 = 1024.00 * KB;
const GB: f32 = 1024.00 * MB;
let ram_usage = self.ram_usage as f32;
let (ram_usage, unit) = if ram_usage < KB {
(ram_usage, "B")
} else if ram_usage < MB {
(ram_usage / KB, "KB")
} else if ram_usage < GB {
(ram_usage / MB, "MB")
} else {
(ram_usage / GB, "GB")
};
write!(
f,
"Benchmark: {}\nJob ID: {}\nElapsed: {:?}\nvCPU: {}\nRAM Usage: {ram_usage:.2} {unit}\n",
self.name, self.job_id, self.elapsed, self.cores,
)
}
}