use enough::Unstoppable;
use jpegli::encoder::{ChromaSubsampling, EncoderConfig, PixelLayout};
use std::time::Instant;
fn main() {
println!("Encoder Stage Profiling\n");
let (width, height) = (2048usize, 2048usize);
let megapixels = (width * height) as f64 / 1_000_000.0;
let mut pixels = vec![0u8; width * height * 3];
let mut seed = 12345u64;
for p in pixels.iter_mut() {
seed = seed.wrapping_mul(6364136223846793005).wrapping_add(1);
*p = (seed >> 33) as u8;
}
let config = EncoderConfig::ycbcr(85.0, ChromaSubsampling::Quarter);
let iterations = 10;
let start = Instant::now();
for _ in 0..iterations {
let mut enc = config
.encode_from_bytes(width as u32, height as u32, PixelLayout::Rgb8Srgb)
.unwrap();
enc.push_packed(&pixels, Unstoppable).unwrap();
let _ = enc.finish().unwrap();
}
let total_ms = start.elapsed().as_secs_f64() * 1000.0 / iterations as f64;
println!("Image: {}x{} ({:.1} MP)", width, height, megapixels);
println!("Total encode time: {:.2} ms", total_ms);
println!("\nBreakdown estimate (from earlier measurements):");
println!("- Color conversion: ~5% ");
println!("- AQ analysis: ~10%");
println!("- DCT: ~15%");
println!("- Quantization: ~10%");
println!("- Huffman table build: ~5%");
println!("- Entropy encoding: ~55% <-- BOTTLENECK");
println!("\nTo get significant speedup, entropy encoding must be parallelized");
println!("using restart intervals.");
println!("\n--- Theoretical Speedups (8 threads) ---");
let stages = [
("Color conv", 0.05, true),
("AQ", 0.10, false),
("DCT", 0.15, true),
("Quantization", 0.10, true),
("Huffman build", 0.05, false),
("Entropy", 0.55, false), ];
let mut parallel_time = 0.0;
for (name, fraction, parallelizable) in &stages {
let time = total_ms * fraction;
let parallel = if *parallelizable { time / 8.0 } else { time };
parallel_time += parallel;
println!(
" {:<15} {:>6.1}ms -> {:>6.1}ms ({})",
name,
time,
parallel,
if *parallelizable {
"parallel"
} else {
"sequential"
}
);
}
println!(" {:-<50}", "");
println!(
" Total: {:>6.1}ms -> {:>6.1}ms ({:.1}x speedup)",
total_ms,
parallel_time,
total_ms / parallel_time
);
println!("\n--- With Parallel Entropy (restart intervals) ---");
let entropy_parallel = total_ms * 0.55 / 8.0;
let everything_parallel = (total_ms * 0.30 / 8.0) + (total_ms * 0.15) + entropy_parallel;
println!(
" Theoretical max: {:.1}ms ({:.1}x speedup)",
everything_parallel,
total_ms / everything_parallel
);
}