use fncache::{backends::memory::MemoryBackend, fncache, init_global_cache, Result};
use std::time::{Duration, Instant};
#[fncache(key_derivation = "runtime")]
fn with_runtime_derivation(a: u32, b: String, c: bool) -> u32 {
println!("Computing with runtime derivation: {}, {}, {}", a, b, c);
std::thread::sleep(Duration::from_millis(10));
if c {
a + b.len() as u32
} else {
a - b.len() as u32
}
}
#[fncache(key_derivation = "compile_time")]
fn with_compile_time_derivation(a: u32, b: String, c: bool) -> u32 {
println!(
"Computing with compile-time derivation: {}, {}, {}",
a, b, c
);
std::thread::sleep(Duration::from_millis(10));
if c {
a + b.len() as u32
} else {
a - b.len() as u32
}
}
fn main() -> Result<()> {
init_global_cache(MemoryBackend::new())?;
println!("Key Derivation Strategies Example");
println!("=================================");
println!("\n--- Runtime Key Derivation ---");
let start = Instant::now();
let result1 = with_runtime_derivation(42, "hello".to_string(), true);
let duration1 = start.elapsed();
println!("First call result: {} (took {:?})", result1, duration1);
let start = Instant::now();
let result2 = with_runtime_derivation(42, "hello".to_string(), true);
let duration2 = start.elapsed();
println!("Second call result: {} (took {:?})", result2, duration2);
let result3 = with_runtime_derivation(42, "world".to_string(), true);
println!("Different args result: {}", result3);
println!("\n--- Compile-time Key Derivation ---");
let start = Instant::now();
let result1 = with_compile_time_derivation(42, "hello".to_string(), true);
let duration1 = start.elapsed();
println!("First call result: {} (took {:?})", result1, duration1);
let start = Instant::now();
let result2 = with_compile_time_derivation(42, "hello".to_string(), true);
let duration2 = start.elapsed();
println!("Second call result: {} (took {:?})", result2, duration2);
let result3 = with_compile_time_derivation(42, "world".to_string(), true);
println!("Different args result: {}", result3);
println!("\n--- Benchmark: 1000 cache hits ---");
let start = Instant::now();
for _ in 0..1000 {
with_runtime_derivation(42, "hello".to_string(), true);
}
let runtime_duration = start.elapsed();
println!("Runtime derivation: {:?}", runtime_duration);
let start = Instant::now();
for _ in 0..1000 {
with_compile_time_derivation(42, "hello".to_string(), true);
}
let compile_time_duration = start.elapsed();
println!("Compile-time derivation: {:?}", compile_time_duration);
println!(
"\nCompile-time is approximately {:.2}x faster for cache hits",
runtime_duration.as_nanos() as f64 / compile_time_duration.as_nanos() as f64
);
Ok(())
}