use fast_ssim2::{Ssimulacra2Config, compute_frame_ssimulacra2_with_config};
use std::time::Instant;
use yuvxyb::{ColorPrimaries, Rgb, TransferCharacteristic};
fn create_test_image_512x512() -> (Rgb, Rgb) {
let width = 512;
let height = 512;
let size = width * height;
let source_data: Vec<[f32; 3]> = (0..size)
.map(|i| {
let x = (i % width) as f32 / width as f32;
let y = (i / width) as f32 / height as f32;
[x, y, (x + y) / 2.0]
})
.collect();
let distorted_data: Vec<[f32; 3]> = source_data
.iter()
.map(|&[r, g, b]| {
[
(r * 0.95).min(1.0),
(g * 1.02).min(1.0),
(b * 0.98).min(1.0),
]
})
.collect();
let nz_width = std::num::NonZeroUsize::new(width).unwrap();
let nz_height = std::num::NonZeroUsize::new(height).unwrap();
let source = Rgb::new(
source_data,
nz_width,
nz_height,
TransferCharacteristic::SRGB,
ColorPrimaries::BT709,
)
.unwrap();
let distorted = Rgb::new(
distorted_data,
nz_width,
nz_height,
TransferCharacteristic::SRGB,
ColorPrimaries::BT709,
)
.unwrap();
(source, distorted)
}
fn benchmark_config(
source: &Rgb,
distorted: &Rgb,
config: Ssimulacra2Config,
iterations: usize,
) -> (f64, f64, f64, f64) {
for _ in 0..3 {
let _ = compute_frame_ssimulacra2_with_config(source.clone(), distorted.clone(), config);
}
let mut times = Vec::with_capacity(iterations);
let mut score = 0.0;
for _ in 0..iterations {
let start = Instant::now();
score = compute_frame_ssimulacra2_with_config(source.clone(), distorted.clone(), config)
.unwrap();
times.push(start.elapsed().as_secs_f64() * 1000.0); }
times.sort_by(|a, b| a.partial_cmp(b).unwrap());
let mean = times.iter().sum::<f64>() / times.len() as f64;
let median = times[times.len() / 2];
let p95 = times[(times.len() as f32 * 0.95) as usize];
(mean, median, p95, score)
}
fn main() {
println!("SSIMULACRA2 Runtime Configuration Benchmark - 512x512 images");
println!("=============================================================\n");
println!("Creating test images...");
let (source, distorted) = create_test_image_512x512();
let iterations = 50;
println!(
"Running benchmarks with {} iterations each...\n",
iterations
);
println!(
"{:<25} {:>10} {:>10} {:>10} {:>12}",
"Configuration", "Mean (ms)", "Median", "P95", "Score"
);
println!("{:-<70}", "");
let config = Ssimulacra2Config::scalar();
let (mean, median, p95, score) = benchmark_config(&source, &distorted, config, iterations);
println!(
"{:<25} {:>10.3} {:>10.3} {:>10.3} {:>12.6}",
"Scalar", mean, median, p95, score
);
let config = Ssimulacra2Config::simd();
let (mean, median, p95, score) = benchmark_config(&source, &distorted, config, iterations);
println!(
"{:<25} {:>10.3} {:>10.3} {:>10.3} {:>12.6}",
"SIMD (archmage)", mean, median, p95, score
);
println!();
}