use clock_hash::{clockhash256, ClockHasher};
use std::time::{Duration, Instant};
#[test]
fn test_basic_performance_baseline() {
let data = b"This is a test message for performance baseline";
let start = Instant::now();
let iterations = 1000;
for _ in 0..iterations {
let _hash = clockhash256(data);
}
let elapsed = start.elapsed();
let avg_time = elapsed / iterations as u32;
assert!(avg_time < Duration::from_micros(100),
"Average hash time too slow: {:?}", avg_time);
}
#[test]
fn test_incremental_performance() {
let data = vec![0x42u8; 1024]; let chunk_size = 64;
let start = Instant::now();
let iterations = 100;
for _ in 0..iterations {
let mut hasher = ClockHasher::new();
for chunk in data.chunks(chunk_size) {
hasher.update(chunk);
}
let _hash = hasher.finalize();
}
let elapsed = start.elapsed();
let avg_time = elapsed / iterations as u32;
assert!(avg_time < Duration::from_millis(1),
"Incremental hashing too slow: {:?}", avg_time);
}
#[test]
fn test_performance_scaling() {
let sizes = [64, 256, 1024, 4096, 16384];
let mut previous_time = Duration::new(0, 0);
for &size in &sizes {
let data: Vec<u8> = (0..size).map(|i| (i % 256) as u8).collect();
let start = Instant::now();
let iterations = 100;
for _ in 0..iterations {
let _hash = clockhash256(&data);
}
let elapsed = start.elapsed();
let avg_time = elapsed / iterations as u32;
if previous_time > Duration::new(0, 0) {
let scaling_factor = avg_time.as_nanos() as f64 / previous_time.as_nanos() as f64;
let size_ratio = size as f64 / (size / 4) as f64;
assert!(scaling_factor < size_ratio * 2.0,
"Performance scaling too poor: {}x slower for {}x larger input",
scaling_factor, size_ratio);
}
previous_time = avg_time;
}
}
#[cfg(feature = "simd")]
#[test]
fn test_simd_performance_advantage() {
use std::time::Instant;
let data = vec![0xAAu8; 1024];
let iterations = 1000;
let start = Instant::now();
for _ in 0..iterations {
let _hash = clockhash256(&data);
}
let elapsed = start.elapsed();
assert!(elapsed < Duration::from_millis(50),
"SIMD performance too slow: {:?}", elapsed);
}
#[test]
fn test_memory_usage_stability() {
let data = b"memory usage test data";
for _ in 0..10 {
let _hash = clockhash256(data);
}
let start_time = Instant::now();
let iterations = 10000;
for _ in 0..iterations {
let _hash = clockhash256(data);
}
let elapsed = start_time.elapsed();
assert!(elapsed < Duration::from_secs(5),
"Memory usage test took too long: {:?}", elapsed);
}
#[test]
fn test_performance_patterns() {
let patterns = vec![
("zeros", vec![0x00; 1024]),
("ones", vec![0xFF; 1024]),
("random", (0..1024).map(|i| (i * 7 + 13) as u8).collect()),
("alternating", (0..1024).map(|i| if i % 2 == 0 { 0xAA } else { 0x55 }).collect()),
];
for (name, data) in patterns {
let start = Instant::now();
let iterations = 100;
for _ in 0..iterations {
let _hash = clockhash256(&data);
}
let elapsed = start.elapsed();
let avg_time = elapsed / iterations as u32;
assert!(avg_time < Duration::from_micros(200),
"Pattern '{}' too slow: {:?}", name, avg_time);
}
}
#[test]
fn test_performance_consistency() {
let data = b"consistency test data";
let mut times = Vec::new();
let iterations = 10;
for _ in 0..iterations {
let start = Instant::now();
for _ in 0..100 {
let _hash = clockhash256(data);
}
let elapsed = start.elapsed();
times.push(elapsed);
}
let avg_time: f64 = times.iter().map(|d| d.as_nanos() as f64).sum::<f64>() / times.len() as f64;
let variance = times.iter()
.map(|d| (d.as_nanos() as f64 - avg_time).powi(2))
.sum::<f64>() / times.len() as f64;
let std_dev = variance.sqrt();
let cv = std_dev / avg_time;
assert!(cv < 0.2, "Performance too inconsistent: CV = {:.3}", cv);
}
#[test]
fn test_domain_performance() {
use clock_hash::{clockhash256_domain, tags};
let data = b"domain performance test";
let start = Instant::now();
let iterations = 1000;
for _ in 0..iterations {
let _hash = clockhash256_domain(tags::CLK_BLOCK, data);
}
let elapsed = start.elapsed();
let avg_time = elapsed / iterations as u32;
assert!(avg_time < Duration::from_micros(150),
"Domain separation too slow: {:?}", avg_time);
}
#[test]
fn test_large_data_throughput() {
let size = 1024 * 1024; let data: Vec<u8> = (0..size).map(|i| (i % 256) as u8).collect();
let start = Instant::now();
let _hash = clockhash256(&data);
let elapsed = start.elapsed();
assert!(elapsed < Duration::from_millis(100),
"Large data hashing too slow: {:?}", elapsed);
let bytes_per_sec = size as f64 / elapsed.as_secs_f64();
let mb_per_sec = bytes_per_sec / (1024.0 * 1024.0);
assert!(mb_per_sec > 10.0,
"Throughput too low: {:.2} MB/s", mb_per_sec);
}