diff --git a/crates/ransac/Cargo.toml b/crates/ransac/Cargo.toml index e5319b355d..84b3c51073 100644 --- a/crates/ransac/Cargo.toml +++ b/crates/ransac/Cargo.toml @@ -14,3 +14,12 @@ nalgebra = { workspace = true } ordered-float = { workspace = true } rand = { workspace = true } rand_chacha = { workspace = true } + +[dev-dependencies] +divan = { workspace = true } +pprof = { workspace = true } + + +[[bench]] +name = "bench" +harness = false diff --git a/crates/ransac/benches/.gitignore b/crates/ransac/benches/.gitignore new file mode 100644 index 0000000000..9b1960e711 --- /dev/null +++ b/crates/ransac/benches/.gitignore @@ -0,0 +1 @@ +output/ \ No newline at end of file diff --git a/crates/ransac/benches/bench.rs b/crates/ransac/benches/bench.rs new file mode 100644 index 0000000000..4e63d1ba83 --- /dev/null +++ b/crates/ransac/benches/bench.rs @@ -0,0 +1,81 @@ +use std::{env, fs::File}; + +use divan::{bench, black_box, AllocProfiler, Bencher}; +use linear_algebra::{point, Point2}; +use pprof::{ProfilerGuard, ProfilerGuardBuilder}; +use rand::SeedableRng; +use rand_chacha::ChaChaRng; +use ransac::circles::{circle::RansacCircle, test_utilities::generate_circle}; + +#[global_allocator] +static ALLOC: AllocProfiler = AllocProfiler::system(); + +fn main() { + divan::main(); +} + +fn get_profiler_guard() -> Option> { + if env::var("ENABLE_FLAMEGRAPH").is_ok_and(|v| v == "1") { + ProfilerGuardBuilder::default() + .frequency(1000) + .blocklist(&["pthread", "vdso"]) + .build() + .ok() + } else { + None + } +} + +fn get_flamegraph(file_name: &str, guard: Option>) { + if let Some(report) = guard.map(|guard| guard.report().build().ok()).flatten() { + let file = File::create(format!( + "{}/benches/output/{}.svg", + env!("CARGO_MANIFEST_DIR"), + file_name + )) + .unwrap(); + report.flamegraph(file).unwrap(); + }; +} + +const TYPICAL_RADIUS: f32 = 0.75; +const GENERATION_VARIATION: f32 = 0.08; +const ACCEPTED_RADIUS_VARIANCE: f32 = 0.1; +const REL_ASSERT_EPSILON: f32 = 1e-5; +const HIGH_POINT_COUNT: usize = 2000; +const HIGH_ITERATIONS: usize = 1500; +const RANDOM_SEED: u64 = 666; + +struct SomeFrame {} + +#[bench(min_time = 30)] +fn noisy_circle(bencher: Bencher) { + let center = point![2.0, 1.5]; + let radius = TYPICAL_RADIUS; + let points: Vec> = generate_circle( + ¢er, + HIGH_POINT_COUNT, + radius, + GENERATION_VARIATION, + RANDOM_SEED, + ); + let mut rng = ChaChaRng::seed_from_u64(RANDOM_SEED); + + let gen = bencher.with_inputs(|| { + let ransac = RansacCircle::::new( + TYPICAL_RADIUS, + ACCEPTED_RADIUS_VARIANCE, + black_box(points.clone()), + ); + ransac + }); + let guard = get_profiler_guard(); + gen.bench_local_values(move |mut ransac| { + black_box( + ransac + .next_candidate(black_box(&mut rng), black_box(HIGH_ITERATIONS)) + .expect("No circle was found"), + ); + }); + get_flamegraph("ransac_noisy_circle", guard); +} diff --git a/crates/ransac/src/circles/mod.rs b/crates/ransac/src/circles/mod.rs index bc300cfe30..889684f21a 100644 --- a/crates/ransac/src/circles/mod.rs +++ b/crates/ransac/src/circles/mod.rs @@ -1,2 +1,2 @@ pub mod circle; -mod test_utilities; +pub mod test_utilities; diff --git a/crates/ransac/src/circles/test_utilities.rs b/crates/ransac/src/circles/test_utilities.rs index 16e54dba28..4f51378b9c 100644 --- a/crates/ransac/src/circles/test_utilities.rs +++ b/crates/ransac/src/circles/test_utilities.rs @@ -9,7 +9,7 @@ use rand::{ use linear_algebra::{point, Point2}; #[allow(dead_code)] -pub(crate) fn generate_circle( +pub fn generate_circle( circle_center: &Point2, point_count: usize, circle_radius: T, diff --git a/webots/worlds/penalized_extern.wbt b/webots/worlds/penalized_extern.wbt index 41bc5817c5..c1068e8c4c 100644 --- a/webots/worlds/penalized_extern.wbt +++ b/webots/worlds/penalized_extern.wbt @@ -1,8 +1,7 @@ -#VRML_SIM R2022b utf8 +#VRML_SIM R2023b utf8 EXTERNPROTO "https://raw.githubusercontent.com/cyberbotics/webots/R2022b/projects/objects/backgrounds/protos/TexturedBackground.proto" EXTERNPROTO "https://raw.githubusercontent.com/cyberbotics/webots/R2022b/projects/objects/backgrounds/protos/TexturedBackgroundLight.proto" -EXTERNPROTO "https://raw.githubusercontent.com/cyberbotics/webots/R2022b/projects/objects/balls/protos/Ball.proto" EXTERNPROTO "../protos/Field.proto" EXTERNPROTO "../protos/SPLBall.proto" EXTERNPROTO "../protos/NAO.proto" @@ -34,8 +33,8 @@ SPLBall { translation -2.5 -1 0.05 } NAO { - translation -3.2 -3 0.333369 - rotation 0 0 1 1.57079632679 + translation -2 -2 0.333369 + rotation 0 0 1 0.8 name "webots2" controller "" supervisor TRUE