diff --git a/geo/Cargo.toml b/geo/Cargo.toml index 59472b99b8..e04c9fe7de 100644 --- a/geo/Cargo.toml +++ b/geo/Cargo.toml @@ -46,6 +46,10 @@ wkt = "0.10.1" name = "area" harness = false +[[bench]] +name = "coordinate_position" +harness = false + [[bench]] name = "contains" harness = false diff --git a/geo/benches/contains.rs b/geo/benches/contains.rs index 564b22441f..3c6219c02c 100644 --- a/geo/benches/contains.rs +++ b/geo/benches/contains.rs @@ -4,7 +4,7 @@ extern crate criterion; extern crate geo; use geo::contains::Contains; -use geo::{polygon, Line, Point, Polygon}; +use geo::{polygon, Line, Point, Polygon, Triangle}; use criterion::Criterion; @@ -116,6 +116,24 @@ fn criterion_benchmark(c: &mut Criterion) { ); }); }); + + c.bench_function("Triangle contains point", |bencher| { + let triangle = Triangle::from([(0., 0.), (10., 0.), (5., 10.)]); + let point = Point::new(5., 5.); + + bencher.iter(|| { + assert!(criterion::black_box(&triangle).contains(criterion::black_box(&point))); + }); + }); + + c.bench_function("Triangle contains point on edge", |bencher| { + let triangle = Triangle::from([(0., 0.), (10., 0.), (6., 10.)]); + let point = Point::new(3., 5.); + + bencher.iter(|| { + assert!(!criterion::black_box(&triangle).contains(criterion::black_box(&point))); + }); + }); } criterion_group!(benches, criterion_benchmark); diff --git a/geo/benches/coordinate_position.rs b/geo/benches/coordinate_position.rs new file mode 100644 index 0000000000..991a187101 --- /dev/null +++ b/geo/benches/coordinate_position.rs @@ -0,0 +1,69 @@ +#[macro_use] +extern crate criterion; +extern crate geo; + +use geo::{ + coordinate_position::CoordPos, BoundingRect, Centroid, CoordinatePosition, Point, Rect, + Triangle, +}; + +use criterion::Criterion; + +fn criterion_benchmark(c: &mut Criterion) { + c.bench_function("Point position to rect", |bencher| { + let plot_centroids: Vec = geo_test_fixtures::nl_plots() + .iter() + .map(|plot| plot.centroid().unwrap()) + .collect(); + let zone_bbox: Vec = geo_test_fixtures::nl_zones() + .iter() + .map(|plot| plot.bounding_rect().unwrap()) + .collect(); + bencher.iter(|| { + let mut inside = 0; + let mut outsied = 0; + let mut boundary = 0; + + for a in &plot_centroids { + for b in &zone_bbox { + criterion::black_box(match b.coordinate_position(&a.0) { + CoordPos::OnBoundary => boundary += 1, + CoordPos::Inside => inside += 1, + CoordPos::Outside => outsied += 1, + }) + } + } + + assert_eq!(inside, 2246); + assert_eq!(outsied, 26510); + assert_eq!(boundary, 0); + }); + }); + + c.bench_function("Point in triangle", |bencher| { + let triangle = Triangle::from([(0., 0.), (10., 0.), (5., 10.)]); + let point = Point::new(5., 5.); + + bencher.iter(|| { + assert!( + criterion::black_box(&triangle).coordinate_position(criterion::black_box(&point.0)) + != CoordPos::Outside + ); + }); + }); + + c.bench_function("Point on triangle boundary", |bencher| { + let triangle = Triangle::from([(0., 0.), (10., 0.), (6., 10.)]); + let point = Point::new(3., 5.); + + bencher.iter(|| { + assert!( + criterion::black_box(&triangle).coordinate_position(criterion::black_box(&point.0)) + == CoordPos::OnBoundary + ); + }); + }); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/geo/benches/intersection.rs b/geo/benches/intersection.rs index ac48ac38cb..29bbe9e249 100644 --- a/geo/benches/intersection.rs +++ b/geo/benches/intersection.rs @@ -65,11 +65,110 @@ fn rect_intersection(c: &mut Criterion) { }); } +fn point_rect_intersection(c: &mut Criterion) { + use geo::algorithm::{BoundingRect, Centroid}; + use geo::geometry::{Point, Rect}; + let plot_centroids: Vec = geo_test_fixtures::nl_plots() + .iter() + .map(|plot| plot.centroid().unwrap()) + .collect(); + let zone_bbox: Vec = geo_test_fixtures::nl_zones() + .iter() + .map(|plot| plot.bounding_rect().unwrap()) + .collect(); + + c.bench_function("Point intersects rect", |bencher| { + bencher.iter(|| { + let mut intersects = 0; + let mut non_intersects = 0; + + for a in &plot_centroids { + for b in &zone_bbox { + if criterion::black_box(a.intersects(b)) { + intersects += 1; + } else { + non_intersects += 1; + } + } + } + + assert_eq!(intersects, 2246); + assert_eq!(non_intersects, 26510); + }); + }); +} + +fn point_triangle_intersection(c: &mut Criterion) { + use geo::{Centroid, TriangulateEarcut}; + use geo_types::{Point, Triangle}; + let plot_centroids: Vec = geo_test_fixtures::nl_plots() + .iter() + .map(|plot| plot.centroid().unwrap()) + .collect(); + let zone_triangles: Vec = geo_test_fixtures::nl_zones() + .iter() + .flat_map(|plot| plot.earcut_triangles_iter()) + .collect(); + + c.bench_function("Point intersects triangle", |bencher| { + bencher.iter(|| { + let mut intersects = 0; + let mut non_intersects = 0; + + for a in &plot_centroids { + for b in &zone_triangles { + if criterion::black_box(a.intersects(b)) { + intersects += 1; + } else { + non_intersects += 1; + } + } + } + + assert_eq!(intersects, 533); + assert_eq!(non_intersects, 5450151); + }); + }); + + c.bench_function("Triangle intersects point", |bencher| { + let triangle = Triangle::from([(0., 0.), (10., 0.), (5., 10.)]); + let point = Point::new(5., 5.); + + bencher.iter(|| { + assert!(criterion::black_box(&triangle).intersects(criterion::black_box(&point))); + }); + }); + + c.bench_function("Triangle intersects point on edge", |bencher| { + let triangle = Triangle::from([(0., 0.), (10., 0.), (6., 10.)]); + let point = Point::new(3., 5.); + + bencher.iter(|| { + assert!(criterion::black_box(&triangle).intersects(criterion::black_box(&point))); + }); + }); +} + criterion_group! { name = bench_multi_polygons; config = Criterion::default().sample_size(10); targets = multi_polygon_intersection } criterion_group!(bench_rects, rect_intersection); +criterion_group! { + name = bench_point_rect; + config = Criterion::default().sample_size(50); + targets = point_rect_intersection +} +criterion_group! { + name = bench_point_triangle; + config = Criterion::default().sample_size(50); + targets = point_triangle_intersection +} -criterion_main!(bench_multi_polygons, bench_rects); +criterion_main!( + bench_multi_polygons, + bench_rects, + bench_point_rect, + bench_point_triangle +);