From 7ce5a60f5fc69f9c47cdae2762b14873d3e90733 Mon Sep 17 00:00:00 2001
From: Tavian Barnes <tavianator@tavianator.com>
Date: Sun, 28 Jun 2020 12:29:07 -0400
Subject: benches: Deduplicate some code with macros

---
 benches/benches.rs | 94 ++++++++++++++++++++++++++++--------------------------
 1 file changed, 48 insertions(+), 46 deletions(-)

diff --git a/benches/benches.rs b/benches/benches.rs
index 3e67c2a..39368d2 100644
--- a/benches/benches.rs
+++ b/benches/benches.rs
@@ -6,7 +6,7 @@ use acap::kd::{FlatKdTree, KdTree};
 use acap::vp::{FlatVpTree, VpTree};
 use acap::NearestNeighbors;
 
-use criterion::{black_box, criterion_group, criterion_main, Criterion};
+use criterion::{black_box, criterion_group, criterion_main, BatchSize, Criterion};
 
 use std::iter::FromIterator;
 
@@ -31,15 +31,27 @@ fn spiral() -> Vec<Point> {
     points
 }
 
-fn bench_from_iter(c: &mut Criterion) {
+fn bench_creation(c: &mut Criterion) {
     let points = black_box(spiral());
 
-    let mut group = c.benchmark_group("from_iter");
-    group.bench_function("ExhaustiveSearch", |b| b.iter(|| ExhaustiveSearch::from_iter(points.clone())));
-    group.bench_function("VpTree", |b| b.iter(|| VpTree::from_iter(points.clone())));
-    group.bench_function("FlatVpTree", |b| b.iter(|| FlatVpTree::from_iter(points.clone())));
-    group.bench_function("KdTree", |b| b.iter(|| KdTree::from_iter(points.clone())));
-    group.bench_function("FlatKdTree", |b| b.iter(|| FlatKdTree::from_iter(points.clone())));
+    let mut group = c.benchmark_group("Creation");
+
+    macro_rules! bench {
+        ($type:ident) => {
+            group.bench_function(stringify!($type), |b| b.iter_batched(
+                || points.clone(),
+                |points| $type::from_iter(points),
+                BatchSize::SmallInput,
+            ));
+        };
+    }
+
+    bench!(ExhaustiveSearch);
+    bench!(VpTree);
+    bench!(FlatVpTree);
+    bench!(KdTree);
+    bench!(FlatKdTree);
+
     group.finish();
 }
 
@@ -47,44 +59,34 @@ fn bench_nearest_neighbors(c: &mut Criterion) {
     let points = black_box(spiral());
     let target = black_box(Euclidean([0.0, 0.0, 0.0]));
 
-    let exhaustive = ExhaustiveSearch::from_iter(points.clone());
-    let vp_tree = VpTree::from_iter(points.clone());
-    let flat_vp_tree = FlatVpTree::from_iter(points.clone());
-    let kd_tree = KdTree::from_iter(points.clone());
-    let flat_kd_tree = FlatKdTree::from_iter(points.clone());
-
-    let mut nearest = c.benchmark_group("NearestNeighbors::nearest");
-    nearest.bench_function("ExhaustiveSearch", |b| b.iter(|| exhaustive.nearest(&target)));
-    nearest.bench_function("VpTree", |b| b.iter(|| vp_tree.nearest(&target)));
-    nearest.bench_function("FlatVpTree", |b| b.iter(|| flat_vp_tree.nearest(&target)));
-    nearest.bench_function("KdTree", |b| b.iter(|| kd_tree.nearest(&target)));
-    nearest.bench_function("FlatKdTree", |b| b.iter(|| flat_kd_tree.nearest(&target)));
-    nearest.finish();
-
-    let mut nearest_within = c.benchmark_group("NearestNeighbors::nearest_within");
-    nearest_within.bench_function("ExhaustiveSearch", |b| b.iter(|| exhaustive.nearest_within(&target, 0.1)));
-    nearest_within.bench_function("VpTree", |b| b.iter(|| vp_tree.nearest_within(&target, 0.1)));
-    nearest_within.bench_function("FlatVpTree", |b| b.iter(|| flat_vp_tree.nearest_within(&target, 0.1)));
-    nearest_within.bench_function("KdTree", |b| b.iter(|| kd_tree.nearest_within(&target, 0.1)));
-    nearest_within.bench_function("FlatKdTree", |b| b.iter(|| flat_kd_tree.nearest_within(&target, 0.1)));
-    nearest_within.finish();
-
-    let mut k_nearest = c.benchmark_group("NearestNeighbors::k_nearest");
-    k_nearest.bench_function("ExhaustiveSearch", |b| b.iter(|| exhaustive.k_nearest(&target, 3)));
-    k_nearest.bench_function("VpTree", |b| b.iter(|| vp_tree.k_nearest(&target, 3)));
-    k_nearest.bench_function("FlatVpTree", |b| b.iter(|| flat_vp_tree.k_nearest(&target, 3)));
-    k_nearest.bench_function("KdTree", |b| b.iter(|| kd_tree.k_nearest(&target, 3)));
-    k_nearest.bench_function("FlatKdTree", |b| b.iter(|| flat_kd_tree.k_nearest(&target, 3)));
-    k_nearest.finish();
-
-    let mut k_nearest_within = c.benchmark_group("NearestNeighbors::k_nearest_within");
-    k_nearest_within.bench_function("ExhaustiveSearch", |b| b.iter(|| exhaustive.k_nearest_within(&target, 3, 0.1)));
-    k_nearest_within.bench_function("VpTree", |b| b.iter(|| vp_tree.k_nearest_within(&target, 3, 0.1)));
-    k_nearest_within.bench_function("FlatVpTree", |b| b.iter(|| flat_vp_tree.k_nearest_within(&target, 3, 0.1)));
-    k_nearest_within.bench_function("KdTree", |b| b.iter(|| kd_tree.k_nearest_within(&target, 3, 0.1)));
-    k_nearest_within.bench_function("FlatKdTree", |b| b.iter(|| flat_kd_tree.k_nearest_within(&target, 3, 0.1)));
-    k_nearest_within.finish();
+    macro_rules! bench {
+        ($type:ident) => {
+            let mut group = c.benchmark_group(stringify!($type));
+            let index = $type::from_iter(points.clone());
+
+            group.bench_function("nearest", |b| b.iter(
+                || index.nearest(&target))
+            );
+            group.bench_function("nearest_within", |b| b.iter(
+                || index.nearest_within(&target, 0.1))
+            );
+            group.bench_function("k_nearest", |b| b.iter(
+                || index.k_nearest(&target, 3))
+            );
+            group.bench_function("k_nearest_within", |b| b.iter(
+                || index.k_nearest_within(&target, 3, 0.1))
+            );
+
+            group.finish();
+        };
+    }
+
+    bench!(ExhaustiveSearch);
+    bench!(VpTree);
+    bench!(FlatVpTree);
+    bench!(KdTree);
+    bench!(FlatKdTree);
 }
 
-criterion_group!(benches, bench_from_iter, bench_nearest_neighbors);
+criterion_group!(benches, bench_creation, bench_nearest_neighbors);
 criterion_main!(benches);
-- 
cgit v1.2.3