use std::time::Instant;
use zeropool::BufferPool;
#[allow(missing_docs)]
const NUM_FILES: usize = 500; const CHUNKS_PER_FILE: usize = 50;
const SIMULATION_RUNS: usize = 3;
#[derive(Clone, Copy)]
enum FileType {
SmallText, MediumJson, LargeImage, VideoChunk, Database, }
impl FileType {
fn chunk_size(self) -> usize {
match self {
FileType::SmallText => 4 * 1024,
FileType::MediumJson => 16 * 1024,
FileType::LargeImage => 64 * 1024,
FileType::VideoChunk => 256 * 1024,
FileType::Database => 1024 * 1024,
}
}
fn all() -> &'static [FileType] {
&[
FileType::SmallText,
FileType::MediumJson,
FileType::LargeImage,
FileType::VideoChunk,
FileType::Database,
]
}
}
fn main() {
eprintln!("=== File Processing Pipeline Profiling ===");
eprintln!("Files to process: {NUM_FILES}");
eprintln!("Chunks per file: {CHUNKS_PER_FILE}");
eprintln!("Simulation runs: {SIMULATION_RUNS}");
eprintln!();
let pool = BufferPool::builder()
.num_shards(8)
.tls_cache_size(4)
.max_buffers_per_shard(24)
.min_buffer_size(4 * 1024)
.build();
eprintln!("Pre-allocating buffers...");
preallocate_buffers(&pool);
let total_start = Instant::now();
for run in 1..=SIMULATION_RUNS {
let run_start = Instant::now();
eprintln!("\n[Run {run}/{SIMULATION_RUNS}] Processing files...");
let bytes_processed = process_all_files(&pool);
let run_duration = run_start.elapsed();
eprintln!(
"[Run {}/{}] Completed in {:.2?}, {:.2} GB processed",
run,
SIMULATION_RUNS,
run_duration,
bytes_processed as f64 / 1e9
);
}
let total_duration = total_start.elapsed();
eprintln!("\n=== Profiling Complete ===");
eprintln!("Total time: {total_duration:.2?}");
eprintln!("Average run time: {:.2?}", total_duration / SIMULATION_RUNS as u32);
eprintln!("Pool stats: {} buffers in pool", pool.len());
}
fn preallocate_buffers(pool: &BufferPool) {
for file_type in FileType::all() {
pool.preallocate(8, file_type.chunk_size());
}
}
fn process_all_files(pool: &BufferPool) -> usize {
let mut total_bytes = 0;
for file_idx in 0..NUM_FILES {
let file_type = select_file_type(file_idx);
total_bytes += process_file(pool, file_type);
}
total_bytes
}
fn select_file_type(index: usize) -> FileType {
FileType::all()[index % FileType::all().len()]
}
fn process_file(pool: &BufferPool, file_type: FileType) -> usize {
let chunk_size = file_type.chunk_size();
let mut total_bytes = 0;
for _ in 0..CHUNKS_PER_FILE {
let mut read_buffer = pool.get(chunk_size);
read_chunk(&mut read_buffer);
total_bytes += read_buffer.len();
transform_data(&mut read_buffer, file_type);
let mut write_buffer = pool.get(chunk_size);
prepare_output(&read_buffer, &mut write_buffer);
write_chunk(&write_buffer);
total_bytes += write_buffer.len();
}
total_bytes
}
fn read_chunk(buffer: &mut [u8]) {
if !buffer.is_empty() {
buffer[0] = 1;
}
}
fn transform_data(buffer: &mut [u8], _file_type: FileType) {
std::hint::black_box(buffer.len());
}
fn prepare_output(input: &[u8], output: &mut [u8]) {
std::hint::black_box(input.len());
if !output.is_empty() {
output[0] = 1;
}
}
fn write_chunk(buffer: &[u8]) {
std::hint::black_box(buffer.len());
}