use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use oxirs_embed::models::common::*;
use scirs2_core::ndarray_ext::{Array1, Array2};
use scirs2_core::random::Random;
use std::hint::black_box;
fn bench_distance_computations(c: &mut Criterion) {
let mut group = c.benchmark_group("distance_computations");
let sizes = vec![100, 500, 1000, 5000];
for size in sizes {
let vectors: Vec<Array1<f64>> = (0..size)
.map(|i| Array1::from_vec(vec![i as f64; 128]))
.collect();
group.bench_with_input(
BenchmarkId::new("optimized_pairwise_distances", size),
&vectors,
|b, vectors| {
b.iter(|| {
black_box(pairwise_distances(vectors));
});
},
);
group.bench_with_input(
BenchmarkId::new("optimized_l2_distance", size),
&vectors,
|b, vectors| {
b.iter(|| {
for i in 0..vectors.len().min(100) {
for j in (i + 1)..vectors.len().min(100) {
black_box(l2_distance(&vectors[i], &vectors[j]));
}
}
});
},
);
group.bench_with_input(
BenchmarkId::new("optimized_cosine_similarity", size),
&vectors,
|b, vectors| {
b.iter(|| {
for i in 0..vectors.len().min(100) {
for j in (i + 1)..vectors.len().min(100) {
black_box(cosine_similarity(&vectors[i], &vectors[j]));
}
}
});
},
);
}
group.finish();
}
fn bench_gradient_updates(c: &mut Criterion) {
let mut group = c.benchmark_group("gradient_updates");
let sizes = vec![100, 500, 1000];
for size in sizes {
let _embeddings: Vec<Array2<f64>> = (0..10).map(|_| Array2::zeros((size, 128))).collect();
let _gradients: Vec<Array2<f64>> = (0..10).map(|_| Array2::ones((size, 128))).collect();
group.bench_with_input(
BenchmarkId::new("batch_gradient_update", size),
&size,
|b, &size| {
let mut embeddings: Vec<Array2<f64>> = (0..size)
.map(|_| Array2::from_elem((128, 64), 0.1))
.collect();
let gradients: Vec<Array2<f64>> = (0..size)
.map(|_| Array2::from_elem((128, 64), 0.01))
.collect();
b.iter(|| {
batch_gradient_update(&mut embeddings, &gradients, 0.01, 0.001);
black_box(());
});
},
);
group.bench_with_input(
BenchmarkId::new("individual_gradient_updates", size),
&size,
|b, &size| {
let mut embeddings: Vec<Array2<f64>> = (0..size)
.map(|_| Array2::from_elem((128, 64), 0.1))
.collect();
let gradients: Vec<Array2<f64>> = (0..size)
.map(|_| Array2::from_elem((128, 64), 0.01))
.collect();
b.iter(|| {
for (embedding, gradient) in embeddings.iter_mut().zip(gradients.iter()) {
gradient_update(embedding, gradient, 0.01, 0.001);
black_box(());
}
});
},
);
}
group.finish();
}
fn bench_sampling_optimizations(c: &mut Criterion) {
let mut group = c.benchmark_group("sampling_optimizations");
let sizes = vec![1000, 5000, 10000];
for size in sizes {
let data: Vec<u32> = (0..size).collect();
let mut rng = Random::default();
group.bench_with_input(
BenchmarkId::new("optimized_sampling_without_replacement", size),
&data,
|b, data| {
b.iter(|| {
black_box(sample_without_replacement(
data,
(size / 10) as usize,
&mut rng,
));
});
},
);
group.bench_with_input(
BenchmarkId::new("optimized_batch_shuffle", size),
&data,
|b, data| {
b.iter(|| {
let mut batch = data.clone();
shuffle_batch(&mut batch, &mut rng);
black_box(());
});
},
);
}
group.finish();
}
fn bench_embedding_initialization(c: &mut Criterion) {
let mut group = c.benchmark_group("embedding_initialization");
let sizes = vec![(100, 128), (500, 256), (1000, 512)];
for (rows, cols) in sizes {
let mut rng = Random::default();
group.bench_with_input(
BenchmarkId::new("batch_xavier_init", format!("{}x{}", rows, cols)),
&(rows, cols),
|b, &(rows, cols)| {
b.iter(|| {
let shapes = vec![(rows, cols); 10];
black_box(batch_xavier_init(&shapes, rows, cols, &mut rng));
});
},
);
group.bench_with_input(
BenchmarkId::new("individual_xavier_init", format!("{}x{}", rows, cols)),
&(rows, cols),
|b, &(rows, cols)| {
b.iter(|| {
for _ in 0..10 {
black_box(xavier_init((rows, cols), rows, cols, &mut rng));
}
});
},
);
}
group.finish();
}
fn bench_batch_processing(c: &mut Criterion) {
let mut group = c.benchmark_group("batch_processing");
let sizes = vec![1000, 5000, 10000];
let batch_size = 32;
for size in sizes {
let data: Vec<u32> = (0..size).collect();
group.bench_with_input(
BenchmarkId::new("zero_copy_batch_refs", size),
&data,
|b, data| {
b.iter(|| {
let batches = create_batch_refs(data, batch_size);
let count = batches.count();
black_box(count);
});
},
);
group.bench_with_input(
BenchmarkId::new("optimized_batch_creation", size),
&data,
|b, data| {
b.iter(|| {
black_box(create_batches(data, batch_size));
});
},
);
}
group.finish();
}
criterion_group!(
benches,
bench_distance_computations,
bench_gradient_updates,
bench_sampling_optimizations,
bench_embedding_initialization,
bench_batch_processing
);
criterion_main!(benches);