use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
use rustorch::tensor::Tensor;
fn create_optimized_benchmark_config() -> Criterion {
Criterion::default()
.sample_size(10) .measurement_time(std::time::Duration::from_secs(2)) .warm_up_time(std::time::Duration::from_secs(1)) .significance_level(0.1) .noise_threshold(0.05) }
fn bench_matrix_decomposition_fast(c: &mut Criterion) {
let mut group = c.benchmark_group("Fast Matrix Decomposition");
group.sample_size(10); group.measurement_time(std::time::Duration::from_secs(1));
group.warm_up_time(std::time::Duration::from_millis(500));
let sizes = vec![4, 8, 12];
for size in sizes {
let matrix_data: Vec<f32> = (0..size * size)
.map(|i| (i as f32 + 1.0) % 8.0 + 1.0)
.collect();
let matrix = Tensor::from_vec(matrix_data, vec![size, size]);
group.bench_with_input(
BenchmarkId::new("SVD", size),
&matrix,
|b, m| b.iter(|| black_box(m.svd())), );
}
group.finish();
}
fn bench_comparison_lightweight(c: &mut Criterion) {
let mut group = c.benchmark_group("Decomposition Comparison Light");
group.sample_size(10);
group.measurement_time(std::time::Duration::from_secs(1));
let size = 8;
let matrix_data: Vec<f32> = (0..size * size)
.map(|i| (i as f32 + 1.0) % 6.0 + 1.0)
.collect();
let matrix = Tensor::from_vec(matrix_data, vec![size, size]);
group.bench_function("SVD_8x8", |b| b.iter(|| black_box(&matrix).svd()));
group.bench_function("QR_8x8", |b| b.iter(|| black_box(&matrix).qr()));
group.bench_function("QR_8x8_alt", |b| b.iter(|| black_box(&matrix).qr()));
let mut sym_data = vec![0.0f32; size * size];
for i in 0..size {
for j in 0..size {
if i == j {
sym_data[i * size + j] = (i + 1) as f32;
} else if i < j {
sym_data[i * size + j] = 0.5;
sym_data[j * size + i] = 0.5;
}
}
}
let sym_matrix = Tensor::from_vec(sym_data, vec![size, size]);
group.bench_function("Symeig_8x8", |b| {
b.iter(|| black_box(&sym_matrix).eigh()) });
group.bench_function("Eig_8x8", |b| {
b.iter(|| black_box(&matrix).eigh()) });
group.finish();
}
fn bench_rectangular_matrices_fast(c: &mut Criterion) {
let mut group = c.benchmark_group("Rectangular Matrices Fast");
group.sample_size(10);
group.measurement_time(std::time::Duration::from_secs(1));
let test_cases = vec![(6, 3, "6x3"), (8, 4, "8x4"), (10, 5, "10x5")];
for (rows, cols, label) in test_cases {
let matrix_data: Vec<f32> = (0..rows * cols)
.map(|i| (i as f32 + 1.0) % 7.0 + 1.0)
.collect();
let matrix = Tensor::from_vec(matrix_data, vec![rows, cols]);
group.bench_with_input(BenchmarkId::new("SVD", label), &matrix, |b, m| {
b.iter(|| black_box(m.svd()))
});
group.bench_with_input(BenchmarkId::new("QR", label), &matrix, |b, m| {
b.iter(|| black_box(m.qr()))
});
}
group.finish();
}
fn bench_scaling_analysis(c: &mut Criterion) {
let mut group = c.benchmark_group("Scaling Analysis");
group.sample_size(10); group.measurement_time(std::time::Duration::from_millis(500));
let sizes = vec![4, 6, 8, 10];
for size in sizes {
let matrix_data: Vec<f32> = (0..size * size)
.map(|i| (i as f32 * 1.3 + 2.1) % 5.0 + 1.0)
.collect();
let matrix = Tensor::from_vec(matrix_data, vec![size, size]);
group.bench_with_input(BenchmarkId::new("SVD_scaling", size), &matrix, |b, m| {
b.iter(|| black_box(m.svd()))
});
}
group.finish();
}
fn bench_with_timeout_protection(c: &mut Criterion) {
let mut group = c.benchmark_group("Timeout Protected Benchmark");
group.sample_size(10);
group.measurement_time(std::time::Duration::from_millis(800));
group.warm_up_time(std::time::Duration::from_millis(200));
let size = 6;
let matrix_data: Vec<f32> = (0..size * size).map(|i| (i + 1) as f32).collect();
let matrix = Tensor::from_vec(matrix_data, vec![size, size]);
group.bench_function("safe_svd", |b| {
b.iter(|| {
let result = black_box(&matrix).svd();
drop(result);
})
});
group.bench_function("safe_qr", |b| {
b.iter(|| {
let result = black_box(&matrix).qr();
drop(result);
})
});
group.finish();
}
criterion_group! {
name = benches;
config = create_optimized_benchmark_config();
targets =
bench_matrix_decomposition_fast,
bench_comparison_lightweight,
bench_rectangular_matrices_fast,
bench_scaling_analysis,
bench_with_timeout_protection
}
criterion_main!(benches);