#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] use criterion::{Criterion, criterion_group, criterion_main}; use pumpkin_data::BlockStateId; use pumpkin_data::dimension::Dimension; use pumpkin_util::world_seed::Seed; use pumpkin_world::chunk_system::{StagedChunkEnum, generate_single_chunk}; use pumpkin_world::generation::get_world_gen; use pumpkin_world::world::WorldPortalExt; use std::hint::black_box; use std::sync::Arc; use std::time::Instant; const SEED: Seed = Seed(42); const THREAD_COUNT: usize = 4; const GRID_SIZE: i32 = 4; // Stub portal — allows all block placements, skips mob spawning. struct BlockRegistry; impl WorldPortalExt for BlockRegistry { fn can_place_at( &self, _block: &pumpkin_data::Block, _state: &pumpkin_data::BlockState, _block_accessor: &dyn pumpkin_world::world::BlockAccessor, _block_pos: &pumpkin_util::math::position::BlockPos, ) -> bool { true } fn mirror( &self, block: &pumpkin_data::Block, state_id: BlockStateId, mirror: pumpkin_data::Mirror, ) -> &'static pumpkin_data::BlockState { block.mirror(state_id, mirror) } fn rotate( &self, block: &pumpkin_data::Block, state_id: BlockStateId, rotation: pumpkin_data::Rotation, ) -> &'static pumpkin_data::BlockState { block.rotate(state_id, rotation) } fn spawn_mobs_for_chunk_generation( &self, _cache: &mut dyn pumpkin_world::generation::proto_chunk::GenerationCache, _biome: &'static pumpkin_data::chunk::Biome, _chunk_x: i32, _chunk_z: i32, ) { } } /// Benchmarks the full pipeline for a `GRID_SIZE^2` chunks grid running in parallel /// across `THREAD_COUNT` rayon threads. fn bench_concurrent_chunk_generation(c: &mut Criterion) { let pool = rayon::ThreadPoolBuilder::new() .num_threads(THREAD_COUNT) .thread_name(|i| format!("bench-chunk-{i}")) .build() .expect("Failed to build rayon thread pool"); let world_gen = Arc::new(get_world_gen( SEED, Dimension::OVERWORLD, false, Vec::new(), String::new(), )); let block_registry = Arc::new(BlockRegistry); let bench_name = format!( "concurrent_full_pipeline_{}_chunks_{}_threads", GRID_SIZE * GRID_SIZE, THREAD_COUNT ); c.bench_function(&bench_name, |b| { b.iter_custom(|iters| { let mut total = std::time::Duration::ZERO; for _ in 0..iters { let wg = world_gen.clone(); let br = block_registry.clone(); let start = Instant::now(); pool.scope(|s| { for cx in 0..GRID_SIZE { for cz in 0..GRID_SIZE { let wg = wg.clone(); let br = br.clone(); s.spawn(move |_| { black_box(generate_single_chunk( &wg, br.as_ref(), cx, cz, StagedChunkEnum::Full, )); }); } } }); total += start.elapsed(); } total }); }); } criterion_group!(benches, bench_concurrent_chunk_generation); criterion_main!(benches);