Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 16 additions & 45 deletions benches/allocation_hot_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ mod allocation_contracts {
use std::{hint::black_box, num::NonZeroUsize, time::Duration};
use thiserror::Error;

use super::bench_utils::{bench_option, bench_result};
use super::bench_utils::{OrAbort, OrAbortWithContext};

const CANARY_COUNT_2D: usize = 4_000;
const CANARY_COUNT_3D: usize = 750;
Expand Down Expand Up @@ -95,21 +95,13 @@ mod allocation_contracts {
}

fn benchmark_bounds() -> CoordinateRange<f64> {
bench_result(
CoordinateRange::try_new(-100.0_f64, 100.0),
"allocation benchmark bounds must be valid",
)
CoordinateRange::try_new(-100.0_f64, 100.0).or_abort()
}

fn canary_vertices<const D: usize>(count: usize, seed: u64) -> Vec<Vertex<(), D>> {
let points = bench_result(
generate_random_points_in_range_seeded::<D>(count, benchmark_bounds(), seed),
"failed to generate allocation benchmark points",
);
bench_result(
try_vertices_from_points(&points),
"failed to create allocation benchmark vertices",
)
let points =
generate_random_points_in_range_seeded::<D>(count, benchmark_bounds(), seed).or_abort();
try_vertices_from_points(&points).or_abort()
}

fn first_simplex_key<const D: usize>(
Expand Down Expand Up @@ -195,10 +187,7 @@ mod allocation_contracts {
}
}

let vertex_count = bench_result(
u32::try_from(points.len()),
"simplex vertex count should fit in u32",
);
let vertex_count = u32::try_from(points.len()).or_abort();
let inv_vertex_count = 1.0 / f64::from(vertex_count);
for coord in &mut coords {
*coord *= inv_vertex_count;
Expand All @@ -214,20 +203,10 @@ mod allocation_contracts {
attempts,
base_seed: Some(seed),
});
let dt = bench_result(
BenchTriangulation::<D>::try_new_with_options(&vertices, options),
format!("failed to build {D}D allocation benchmark triangulation"),
);
let simplex_key =
bench_result(representative_simplex_key(&dt), "missing benchmark simplex");
let facet_vertices = bench_result(
first_facet_vertices(&dt, simplex_key),
"failed to prepare benchmark facet vertices",
);
let query = bench_result(
simplex_barycenter(&dt, simplex_key),
"failed to prepare benchmark locate query",
);
let dt = BenchTriangulation::<D>::try_new_with_options(&vertices, options).or_abort();
let simplex_key = representative_simplex_key(&dt).or_abort();
let facet_vertices = first_facet_vertices(&dt, simplex_key).or_abort();
let query = simplex_barycenter(&dt, simplex_key).or_abort();
let simplex_count = dt.tds().simplices().count();
let vertex_count = dt.tds().vertices().count();

Expand Down Expand Up @@ -349,10 +328,7 @@ mod allocation_contracts {
let (vertex_count, info) = measure_with_result(|| {
tds.simplex_vertices(simplex_key).map(|keys| keys.len())
});
assert_eq!(
bench_result(vertex_count, "Tds::simplex_vertices should succeed"),
D + 1
);
assert_eq!(vertex_count.or_abort(), D + 1);
assert_zero_allocations(&info, "Tds::simplex_vertices");
});
},
Expand All @@ -364,10 +340,9 @@ mod allocation_contracts {
fixture: &DimensionFixture<D>,
) {
let tds = fixture.dt.tds();
let simplex = bench_option(
tds.simplex(fixture.simplex_key),
format!("{D}D benchmark simplex should exist"),
);
let simplex = tds
.simplex(fixture.simplex_key)
.or_abort(format!("{D}D benchmark simplex should exist"));

group.bench_function(
BenchmarkId::new(
Expand All @@ -381,10 +356,7 @@ mod allocation_contracts {
.vertex_uuid_iter(tds)
.try_fold(0usize, |count, uuid| uuid.map(|_| count + 1))
});
assert_eq!(
bench_result(uuid_count, "Simplex::vertex_uuid_iter should succeed"),
D + 1
);
assert_eq!(uuid_count.or_abort(), D + 1);
assert_zero_allocations(&info, "Simplex::vertex_uuid_iter");
});
},
Expand Down Expand Up @@ -429,8 +401,7 @@ mod allocation_contracts {
let (locate_result, info) = measure_with_result(|| {
locate_with_stats(fixture.dt.tds(), &kernel, &fixture.query, Some(simplex_key))
});
let (location, stats) =
bench_result(locate_result, "hinted locate_with_stats should succeed");
let (location, stats) = locate_result.or_abort();

assert_matches!(location, LocateResult::InsideSimplex(found) if found == simplex_key);
assert!(stats.used_hint);
Expand Down
110 changes: 40 additions & 70 deletions benches/boundary_uuid_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//! preserving the quick performance probes.

use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};
use delaunay::prelude::construction::DelaunayTriangulation;
use delaunay::prelude::construction::{DelaunayTriangulation, Vertex};
use delaunay::prelude::generators::generate_random_points_in_range_seeded;
use delaunay::prelude::geometry::CoordinateRange;
use delaunay::prelude::query::BoundaryAnalysis;
Expand All @@ -20,15 +20,12 @@ use std::hint::black_box;
/// Shared benchmark setup error helpers.
#[path = "common/bench_utils.rs"]
pub mod bench_utils;
use bench_utils::{bench_option, bench_result};
use bench_utils::{OrAbort, OrAbortWithContext};

const BOUNDARY_COUNTS_3D: &[usize] = &[20, 40, 60, 80];

fn benchmark_bounds() -> CoordinateRange<f64> {
bench_result(
CoordinateRange::try_new(-100.0_f64, 100.0),
"boundary benchmark bounds must be valid",
)
CoordinateRange::try_new(-100.0_f64, 100.0).or_abort()
}

fn boundary_triangulation_3d(
Expand All @@ -39,64 +36,53 @@ fn boundary_triangulation_3d(
benchmark_bounds(),
0xB0DA_FACE_0000_0000 ^ requested_vertices as u64,
);
let points = bench_result(points, "failed to generate boundary benchmark points");
let vertices = bench_result(
try_vertices_from_points(&points),
"failed to create boundary benchmark vertices",
);
bench_result(
DelaunayTriangulation::try_new(&vertices),
"failed to build 3D boundary benchmark triangulation",
)
let points = points.or_abort();
let vertices = try_vertices_from_points(&points).or_abort();
DelaunayTriangulation::try_new(&vertices).or_abort()
}

fn bench_boundary_facets_micro(c: &mut Criterion) {
let mut group = c.benchmark_group("boundary_facets_micro");

for &requested_vertices in BOUNDARY_COUNTS_3D {
let dt = boundary_triangulation_3d(requested_vertices);
let boundary_count = bench_result(
bench_result(dt.boundary_facets(), "boundary facets should be available")
.try_fold(0_usize, |count, facet| facet.map(|_| count + 1)),
"boundary facets should be valid",
);
group.throughput(Throughput::Elements(bench_result(
u64::try_from(boundary_count),
"boundary facet count fits in u64",
)));
let boundary_count = dt
.boundary_facets()
.or_abort()
.try_fold(0_usize, |count, facet| facet.map(|_| count + 1))
.or_abort();
group.throughput(Throughput::Elements(
u64::try_from(boundary_count).or_abort(),
));

group.bench_with_input(
BenchmarkId::new("boundary_facets_count_3d", requested_vertices),
&dt,
|b, dt| {
b.iter(|| {
black_box(bench_result(
bench_result(dt.boundary_facets(), "boundary facets should be available")
.try_fold(0_usize, |count, facet| facet.map(|_| count + 1)),
"boundary facets should be valid",
));
black_box(
dt.boundary_facets()
.or_abort()
.try_fold(0_usize, |count, facet| facet.map(|_| count + 1))
.or_abort(),
);
});
},
);

let boundary_facets = bench_result(
bench_result(dt.boundary_facets(), "boundary facets should be available")
.collect::<Result<Vec<_>, _>>(),
"boundary facets should be valid",
);
let boundary_facets = dt
.boundary_facets()
.or_abort()
.collect::<Result<Vec<_>, _>>()
.or_abort();
group.bench_with_input(
BenchmarkId::new("is_boundary_facet_3d", requested_vertices),
&(&dt, boundary_facets),
|b, (dt, facets)| {
b.iter(|| {
let confirmed = facets
.iter()
.filter(|facet| {
bench_result(
dt.tds().is_boundary_facet(facet),
"boundary facet check should succeed",
)
})
.filter(|facet| dt.tds().is_boundary_facet(facet).or_abort())
.count();
black_box(confirmed);
});
Expand All @@ -110,48 +96,32 @@ fn bench_boundary_facets_micro(c: &mut Criterion) {
fn uuid_iter_source()
-> DelaunayTriangulation<delaunay::prelude::geometry::AdaptiveKernel<f64>, (), (), 3> {
let vertices = vec![
bench_result(
delaunay::prelude::Vertex::<(), _>::try_new([0.0, 0.0, 0.0]),
"finite benchmark vertex coordinates",
),
bench_result(
delaunay::prelude::Vertex::<(), _>::try_new([1.0, 0.0, 0.0]),
"finite benchmark vertex coordinates",
),
bench_result(
delaunay::prelude::Vertex::<(), _>::try_new([0.0, 1.0, 0.0]),
"finite benchmark vertex coordinates",
),
bench_result(
delaunay::prelude::Vertex::<(), _>::try_new([0.0, 0.0, 1.0]),
"finite benchmark vertex coordinates",
),
Vertex::<(), _>::try_new([0.0, 0.0, 0.0]).or_abort(),
Vertex::<(), _>::try_new([1.0, 0.0, 0.0]).or_abort(),
Vertex::<(), _>::try_new([0.0, 1.0, 0.0]).or_abort(),
Vertex::<(), _>::try_new([0.0, 0.0, 1.0]).or_abort(),
];
bench_result(
DelaunayTriangulation::try_new(&vertices),
"failed to build UUID iterator benchmark triangulation",
)
DelaunayTriangulation::try_new(&vertices).or_abort()
}

fn bench_vertex_uuid_iter(c: &mut Criterion) {
let mut group = c.benchmark_group("vertex_uuid_iter");
let dt = uuid_iter_source();
let (_simplex_key, simplex) = bench_option(
dt.simplices().next(),
"simplex should exist for UUID iterator benchmark",
);
let (_simplex_key, simplex) = dt
.simplices()
.next()
.or_abort("simplex should exist for UUID iterator benchmark");

group.throughput(Throughput::Elements(bench_result(
u64::try_from(simplex.vertices().len()),
"vertex count fits in u64",
)));
group.throughput(Throughput::Elements(
u64::try_from(simplex.vertices().len()).or_abort(),
));

group.bench_function("by_value", |b| {
b.iter(|| {
let unique_uuids = simplex
.vertex_uuid_iter(dt.tds())
.collect::<Result<HashSet<_>, _>>();
let unique_uuids = bench_result(unique_uuids, "UUID iteration should succeed");
let unique_uuids = unique_uuids.or_abort();
black_box(unique_uuids);
});
});
Expand All @@ -161,7 +131,7 @@ fn bench_vertex_uuid_iter(c: &mut Criterion) {
let uuid_values: Vec<Uuid> = simplex
.vertices()
.iter()
.map(|&vkey| bench_option(dt.tds().vertex(vkey), "vertex should exist").uuid())
.map(|&vkey| dt.tds().vertex(vkey).or_abort("vertex should exist").uuid())
.collect();
let uuid_refs: Vec<&Uuid> = uuid_values.iter().collect();
black_box(uuid_refs);
Expand Down
Loading
Loading