mirror of
https://github.com/PatchRequest/BusyWork
synced 2026-06-09 16:04:04 +00:00
5d5f15a7da
Pattern-breaking sleep replacement that executes real, varied work on every call. Randomized task selection across 7 categories (compute, memory, filesystem, registry, winapi, network, crypto) with intensity levels and jitter. Zero time objects in the library binary.
170 lines
4.7 KiB
Rust
170 lines
4.7 KiB
Rust
use busywork::{busywork, busywork_with, BusyWork, Categories, Intensity};
|
|
use std::time::Instant;
|
|
|
|
fn measure<F: FnOnce()>(f: F) -> f64 {
|
|
let start = Instant::now();
|
|
f();
|
|
start.elapsed().as_secs_f64() * 1000.0
|
|
}
|
|
|
|
fn avg_ms<F: Fn()>(runs: usize, f: F) -> (f64, f64, f64) {
|
|
let mut times = Vec::with_capacity(runs);
|
|
for _ in 0..runs {
|
|
times.push(measure(|| f()));
|
|
}
|
|
times.sort_by(|a, b| a.partial_cmp(b).unwrap());
|
|
let min = times[0];
|
|
let max = times[times.len() - 1];
|
|
let avg = times.iter().sum::<f64>() / times.len() as f64;
|
|
(min, avg, max)
|
|
}
|
|
|
|
#[test]
|
|
fn bench_intensities() {
|
|
let runs = 5;
|
|
println!("\n{:=<70}", "");
|
|
println!(" INTENSITY BENCHMARKS ({} runs each, all categories)", runs);
|
|
println!("{:=<70}", "");
|
|
println!(
|
|
" {:10} {:>12} {:>12} {:>12}",
|
|
"Level", "Min (ms)", "Avg (ms)", "Max (ms)"
|
|
);
|
|
println!("{:-<70}", "");
|
|
|
|
for (name, intensity) in [
|
|
("Low", Intensity::Low),
|
|
("Medium", Intensity::Medium),
|
|
("High", Intensity::High),
|
|
("Ultra", Intensity::Ultra),
|
|
] {
|
|
let (min, avg, max) = avg_ms(runs, || busywork(intensity));
|
|
println!(
|
|
" {:10} {:>12.2} {:>12.2} {:>12.2}",
|
|
name, min, avg, max
|
|
);
|
|
}
|
|
println!("{:=<70}\n", "");
|
|
}
|
|
|
|
#[test]
|
|
fn bench_categories_medium() {
|
|
let runs = 5;
|
|
println!("\n{:=<70}", "");
|
|
println!(
|
|
" CATEGORY BENCHMARKS @ Medium ({} runs each, single category)",
|
|
runs
|
|
);
|
|
println!("{:=<70}", "");
|
|
println!(
|
|
" {:14} {:>12} {:>12} {:>12}",
|
|
"Category", "Min (ms)", "Avg (ms)", "Max (ms)"
|
|
);
|
|
println!("{:-<70}", "");
|
|
|
|
let cats: &[(&str, Categories)] = &[
|
|
("COMPUTE", Categories::COMPUTE),
|
|
("MEMORY", Categories::MEMORY),
|
|
("FILESYSTEM", Categories::FILESYSTEM),
|
|
("REGISTRY", Categories::REGISTRY),
|
|
("WINAPI", Categories::WINAPI),
|
|
("NETWORK", Categories::NETWORK),
|
|
("CRYPTO", Categories::CRYPTO),
|
|
];
|
|
|
|
for &(name, cat) in cats {
|
|
let (min, avg, max) = avg_ms(runs, || busywork_with(Intensity::Medium, cat));
|
|
println!(
|
|
" {:14} {:>12.2} {:>12.2} {:>12.2}",
|
|
name, min, avg, max
|
|
);
|
|
}
|
|
println!("{:=<70}\n", "");
|
|
}
|
|
|
|
#[test]
|
|
fn bench_categories_high() {
|
|
let runs = 3;
|
|
println!("\n{:=<70}", "");
|
|
println!(
|
|
" CATEGORY BENCHMARKS @ High ({} runs each, single category)",
|
|
runs
|
|
);
|
|
println!("{:=<70}", "");
|
|
println!(
|
|
" {:14} {:>12} {:>12} {:>12}",
|
|
"Category", "Min (ms)", "Avg (ms)", "Max (ms)"
|
|
);
|
|
println!("{:-<70}", "");
|
|
|
|
let cats: &[(&str, Categories)] = &[
|
|
("COMPUTE", Categories::COMPUTE),
|
|
("MEMORY", Categories::MEMORY),
|
|
("FILESYSTEM", Categories::FILESYSTEM),
|
|
("REGISTRY", Categories::REGISTRY),
|
|
("WINAPI", Categories::WINAPI),
|
|
("NETWORK", Categories::NETWORK),
|
|
("CRYPTO", Categories::CRYPTO),
|
|
];
|
|
|
|
for &(name, cat) in cats {
|
|
let (min, avg, max) = avg_ms(runs, || busywork_with(Intensity::High, cat));
|
|
println!(
|
|
" {:14} {:>12.2} {:>12.2} {:>12.2}",
|
|
name, min, avg, max
|
|
);
|
|
}
|
|
println!("{:=<70}\n", "");
|
|
}
|
|
|
|
#[test]
|
|
fn bench_jitter_variance() {
|
|
let runs = 10;
|
|
println!("\n{:=<70}", "");
|
|
println!(" JITTER VARIANCE (Medium, COMPUTE only, {} runs)", runs);
|
|
println!("{:=<70}", "");
|
|
|
|
let mut with_jitter = Vec::new();
|
|
let mut without_jitter = Vec::new();
|
|
|
|
for _ in 0..runs {
|
|
with_jitter.push(measure(|| {
|
|
BusyWork::new(Intensity::Medium)
|
|
.allow(Categories::COMPUTE)
|
|
.jitter(true)
|
|
.run();
|
|
}));
|
|
without_jitter.push(measure(|| {
|
|
BusyWork::new(Intensity::Medium)
|
|
.allow(Categories::COMPUTE)
|
|
.jitter(false)
|
|
.run();
|
|
}));
|
|
}
|
|
|
|
let variance = |times: &[f64]| -> f64 {
|
|
let avg = times.iter().sum::<f64>() / times.len() as f64;
|
|
let var = times.iter().map(|t| (t - avg).powi(2)).sum::<f64>() / times.len() as f64;
|
|
var.sqrt()
|
|
};
|
|
|
|
let jitter_avg = with_jitter.iter().sum::<f64>() / runs as f64;
|
|
let no_jitter_avg = without_jitter.iter().sum::<f64>() / runs as f64;
|
|
let jitter_std = variance(&with_jitter);
|
|
let no_jitter_std = variance(&without_jitter);
|
|
|
|
println!(
|
|
" {:20} {:>10} {:>10}",
|
|
"", "Avg (ms)", "StdDev"
|
|
);
|
|
println!("{:-<70}", "");
|
|
println!(
|
|
" {:20} {:>10.2} {:>10.2}",
|
|
"Jitter ON", jitter_avg, jitter_std
|
|
);
|
|
println!(
|
|
" {:20} {:>10.2} {:>10.2}",
|
|
"Jitter OFF", no_jitter_avg, no_jitter_std
|
|
);
|
|
println!("{:=<70}\n", "");
|
|
}
|