use cute_dsp::perf::{StopDenormals, mul, mul_conj};
use num_complex::Complex;
use std::time::{Duration, Instant};
fn main() {
println!("Performance Utilities Example");
println!("============================");
complex_multiplication_example();
stop_denormals_example();
performance_comparison_example();
}
fn complex_multiplication_example() {
println!("\nComplex Multiplication Example:");
let a = Complex::new(2.0, 3.0);
let b = Complex::new(4.0, 5.0);
let standard_result = a * b;
println!("Standard multiplication: ({}, {}) * ({}, {}) = ({}, {})",
a.re, a.im, b.re, b.im, standard_result.re, standard_result.im);
let optimized_result = mul(a, b);
println!("Optimized multiplication: ({}, {}) * ({}, {}) = ({}, {})",
a.re, a.im, b.re, b.im, optimized_result.re, optimized_result.im);
let conj_result = mul_conj(a, b);
println!("Multiplication with conjugate: ({}, {}) * ({}, {})* = ({}, {})",
a.re, a.im, b.re, b.im, conj_result.re, conj_result.im);
let b_conj = Complex::new(b.re, -b.im);
let standard_conj_result = a * b_conj;
println!("Standard multiplication with conjugate: ({}, {}) * ({}, {}) = ({}, {})",
a.re, a.im, b_conj.re, b_conj.im, standard_conj_result.re, standard_conj_result.im);
}
fn stop_denormals_example() {
println!("\nStop Denormals Example:");
let mut small_value = 1.0e-30;
println!("Initial small value: {}", small_value);
for i in 0..10 {
small_value *= 0.1;
println!("Iteration {}: value = {}", i, small_value);
}
println!("\nNow with StopDenormals active:");
let _stop_denormals = StopDenormals::new();
small_value = 1.0e-30;
println!("Initial small value: {}", small_value);
for i in 0..10 {
small_value *= 0.1;
println!("Iteration {}: value = {}", i, small_value);
}
println!("StopDenormals is automatically disabled when it goes out of scope");
}
fn performance_comparison_example() {
println!("\nPerformance Comparison Example:");
const NUM_ITERATIONS: usize = 1_000_000;
const ARRAY_SIZE: usize = 1000;
let mut a = vec![Complex::new(0.0, 0.0); ARRAY_SIZE];
let mut b = vec![Complex::new(0.0, 0.0); ARRAY_SIZE];
let mut c_standard = vec![Complex::new(0.0, 0.0); ARRAY_SIZE];
let mut c_optimized = vec![Complex::new(0.0, 0.0); ARRAY_SIZE];
for i in 0..ARRAY_SIZE {
a[i] = Complex::new(i as f32 * 0.01, (i as f32 + 0.5) * 0.01);
b[i] = Complex::new((i as f32 + 0.3) * 0.01, (i as f32 + 0.7) * 0.01);
}
println!("Testing standard complex multiplication...");
let start = Instant::now();
for _ in 0..NUM_ITERATIONS / ARRAY_SIZE {
for i in 0..ARRAY_SIZE {
c_standard[i] = a[i] * b[i];
}
}
let standard_duration = start.elapsed();
println!("Testing optimized complex multiplication...");
let start = Instant::now();
for _ in 0..NUM_ITERATIONS / ARRAY_SIZE {
for i in 0..ARRAY_SIZE {
c_optimized[i] = mul(a[i], b[i]);
}
}
let optimized_duration = start.elapsed();
println!("Standard multiplication time: {:?}", standard_duration);
println!("Optimized multiplication time: {:?}", optimized_duration);
if optimized_duration < standard_duration {
let speedup = standard_duration.as_nanos() as f64 / optimized_duration.as_nanos() as f64;
println!("Optimized version is {:.2}x faster", speedup);
} else {
let slowdown = optimized_duration.as_nanos() as f64 / standard_duration.as_nanos() as f64;
println!("Optimized version is {:.2}x slower", slowdown);
}
println!("\nTesting with StopDenormals...");
println!("Without StopDenormals:");
let start = Instant::now();
for _ in 0..NUM_ITERATIONS / ARRAY_SIZE {
for i in 0..ARRAY_SIZE {
c_standard[i] = a[i] * b[i] * Complex::new(1e-30, 1e-30);
}
}
let without_stop_denormals = start.elapsed();
println!("Time: {:?}", without_stop_denormals);
println!("With StopDenormals:");
let _stop_denormals = StopDenormals::new();
let start = Instant::now();
for _ in 0..NUM_ITERATIONS / ARRAY_SIZE {
for i in 0..ARRAY_SIZE {
c_standard[i] = a[i] * b[i] * Complex::new(1e-30, 1e-30);
}
}
let with_stop_denormals = start.elapsed();
println!("Time: {:?}", with_stop_denormals);
if with_stop_denormals < without_stop_denormals {
let speedup = without_stop_denormals.as_nanos() as f64 / with_stop_denormals.as_nanos() as f64;
println!("With StopDenormals is {:.2}x faster", speedup);
} else {
let slowdown = with_stop_denormals.as_nanos() as f64 / without_stop_denormals.as_nanos() as f64;
println!("With StopDenormals is {:.2}x slower", slowdown);
}
}