diff --git a/.gitignore b/.gitignore index 96ef6c0..e24c52a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target Cargo.lock +*.svg diff --git a/Cargo.toml b/Cargo.toml index eb568e8..c95e82e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,3 +13,13 @@ ordered-float = "2.0" rand = { version = "0.8", features = ["small_rng"] } rayon = "1.5" serde = { version = "1.0.118", features = ["derive"], optional = true } + +[dev-dependencies] +bencher = "0.1.5" + +[[bench]] +name = "all" +harness = false + +[profile.bench] +debug = true diff --git a/benches/all.rs b/benches/all.rs new file mode 100644 index 0000000..df88014 --- /dev/null +++ b/benches/all.rs @@ -0,0 +1,57 @@ +use bencher::{benchmark_group, benchmark_main, Bencher}; +use rand::rngs::{StdRng, ThreadRng}; +use rand::{Rng, SeedableRng}; + +use instant_distance::Builder; + +benchmark_main!(benches); +benchmark_group!(benches, build_heuristic); + +fn build_heuristic(bench: &mut Bencher) { + let seed = ThreadRng::default().gen::(); + let mut rng = StdRng::seed_from_u64(seed); + let points = (0..1024) + .into_iter() + .map(|_| Point(rng.gen(), rng.gen())) + .collect::>(); + + bench.iter(|| Builder::default().seed(seed).build(&points)) +} + +/* +fn randomized(builder: Builder) -> (u64, usize) { + let query = Point(rng.gen(), rng.gen()); + let mut nearest = Vec::with_capacity(256); + for (i, p) in points.iter().enumerate() { + nearest.push((OrderedFloat::from(query.distance(p)), i)); + if nearest.len() >= 200 { + nearest.sort_unstable(); + nearest.truncate(100); + } + } + + let mut search = Search::default(); + let mut results = vec![PointId::default(); 100]; + let found = hnsw.search(&query, &mut results, &mut search); + assert_eq!(found, 100); + + nearest.sort_unstable(); + nearest.truncate(100); + let forced = nearest + .iter() + .map(|(_, i)| pids[*i]) + .collect::>(); + let found = results.into_iter().take(found).collect::>(); + (seed, forced.intersection(&found).count()) +} +*/ + +#[derive(Clone, Copy, Debug)] +struct Point(f32, f32); + +impl instant_distance::Point for Point { + fn distance(&self, other: &Self) -> f32 { + // Euclidean distance metric + ((self.0 - other.0).powi(2) + (self.1 - other.1).powi(2)).sqrt() + } +}