use std::time::Instant;
use packed_spatial_index::experimental::ExperimentalSortKey2D;
use packed_spatial_index::{Box2D, Index2DBuilder};
use rand::rngs::StdRng;
use rand::{RngExt, SeedableRng};
const N: usize = 100_000;
const NQ: usize = 1_000;
const REPS_Q: usize = 200;
const REPS_B: usize = 50;
fn main() {
let mut rng = StdRng::seed_from_u64(0xB0B);
let boxes: Vec<[f64; 4]> = (0..N)
.map(|_| {
let cx: f64 = rng.random_range(0.0..10_000.0);
let cy: f64 = rng.random_range(0.0..10_000.0);
let w: f64 = rng.random_range(0.1..20.0);
let h: f64 = rng.random_range(0.1..20.0);
[cx, cy, cx + w, cy + h]
})
.collect();
let mut qrng = StdRng::seed_from_u64(0xACE);
let queries: Vec<[f64; 4]> = (0..NQ)
.map(|_| {
let qx: f64 = qrng.random_range(0.0..10_000.0);
let qy: f64 = qrng.random_range(0.0..10_000.0);
let qw: f64 = qrng.random_range(10.0..200.0);
let qh: f64 = qrng.random_range(10.0..200.0);
[qx, qy, qx + qw, qy + qh]
})
.collect();
println!(
"N={N}, queries={NQ}\n{:>9} | {:>11} | {:>12} | {:>12}",
"node_size", "build(serial)", "query AVX2", "query AVX-512"
);
println!("{}", "-".repeat(54));
for &ns in &[4usize, 8, 16, 32, 64] {
let mut bbest = f64::INFINITY;
for _ in 0..REPS_B {
let t = Instant::now();
let mut b = Index2DBuilder::new(N)
.node_size(ns)
.experimental_sort_key(ExperimentalSortKey2D::HilbertLut);
for r in &boxes {
b.add(Box2D::new(r[0], r[1], r[2], r[3]));
}
let idx = b.finish().unwrap();
bbest = bbest.min(t.elapsed().as_secs_f64() * 1e3);
std::hint::black_box(idx.num_items());
}
let mut sb = Index2DBuilder::new(N)
.node_size(ns)
.experimental_sort_key(ExperimentalSortKey2D::HilbertLut);
for r in &boxes {
sb.add(Box2D::new(r[0], r[1], r[2], r[3]));
}
let soa = sb.finish_simd().unwrap();
let (mut buf, mut st) = (Vec::new(), Vec::new());
let mut q2 = f64::INFINITY;
for _ in 0..REPS_Q {
let t = Instant::now();
let mut tot = 0;
for x in &queries {
soa.search_simd(Box2D::new(x[0], x[1], x[2], x[3]), &mut buf, &mut st);
tot += buf.len();
}
std::hint::black_box(tot);
q2 = q2.min(t.elapsed().as_secs_f64() * 1e6);
}
let mut q8 = f64::INFINITY;
for _ in 0..REPS_Q {
let t = Instant::now();
let mut tot = 0;
for x in &queries {
soa.search_avx512(Box2D::new(x[0], x[1], x[2], x[3]), &mut buf, &mut st);
tot += buf.len();
}
std::hint::black_box(tot);
q8 = q8.min(t.elapsed().as_secs_f64() * 1e6);
}
println!(
"{:>9} | {:>8.3} ms | {:>9.1} µs | {:>9.1} µs",
ns, bbest, q2, q8
);
}
}