mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-31 08:22:33 +00:00
Optimization ChunkNoiseFunctionComponent (#1037)
* feat(chunk): optimize heap allocations of destiny function * refactor: applied `cargo fmt` and linting error * fix(benches): fix lint errors
This commit is contained in:
@@ -70,3 +70,7 @@ harness = false
|
||||
[[bench]]
|
||||
name = "chunk_gen"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "noise_router"
|
||||
harness = false
|
||||
|
||||
34
pumpkin-world/benches/noise_router.rs
Normal file
34
pumpkin-world/benches/noise_router.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
use criterion::{Criterion, criterion_group, criterion_main};
|
||||
use pumpkin_data::noise_router::OVERWORLD_BASE_NOISE_ROUTER;
|
||||
use pumpkin_world::generation::{
|
||||
GlobalRandomConfig,
|
||||
noise_router::{
|
||||
chunk_density_function::ChunkNoiseFunctionBuilderOptions,
|
||||
chunk_noise_router::ChunkNoiseRouter, proto_noise_router::ProtoNoiseRouters,
|
||||
},
|
||||
};
|
||||
use std::hint::black_box;
|
||||
|
||||
fn bench_noise_router_creation(c: &mut Criterion) {
|
||||
let base_routers = &OVERWORLD_BASE_NOISE_ROUTER;
|
||||
let random_config = GlobalRandomConfig::new(0, false);
|
||||
|
||||
let proto_routers = ProtoNoiseRouters::generate(base_routers, &random_config);
|
||||
let proto_noise_router = proto_routers.noise;
|
||||
|
||||
let builder_options = ChunkNoiseFunctionBuilderOptions::new(4, 8, 4, 4, 0, 0, 3);
|
||||
|
||||
// Benchmarking
|
||||
c.bench_function("noise_router_creation_with_pooling", |b| {
|
||||
b.iter(|| {
|
||||
let router = ChunkNoiseRouter::generate(
|
||||
black_box(&proto_noise_router),
|
||||
black_box(&builder_options),
|
||||
);
|
||||
black_box(router);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench_noise_router_creation);
|
||||
criterion_main!(benches);
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::cell::RefCell;
|
||||
use std::mem;
|
||||
|
||||
use super::{
|
||||
@@ -9,6 +10,36 @@ use pumpkin_util::math::{lerp, lerp3, vector2::Vector2};
|
||||
|
||||
use crate::generation::{biome_coords, positions::chunk_pos};
|
||||
|
||||
thread_local! {
|
||||
static F64_BUFFER_POOL: RefCell<Vec<Vec<f64>>> = const {
|
||||
RefCell::new(Vec::new())
|
||||
};
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_buffer(len: usize) -> Box<[f64]> {
|
||||
F64_BUFFER_POOL.with(|pool| {
|
||||
let mut buffers = pool.borrow_mut();
|
||||
if let Some(mut buf) = buffers.pop() {
|
||||
if buf.len() != len {
|
||||
buf.resize(len, 0.0);
|
||||
} else {
|
||||
buf.fill(0.0);
|
||||
}
|
||||
buf.into_boxed_slice()
|
||||
} else {
|
||||
vec![0.0; len].into_boxed_slice()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn recycle_buffer(buf: Box<[f64]>) {
|
||||
F64_BUFFER_POOL.with(|pool| {
|
||||
pool.borrow_mut().push(Vec::from(buf));
|
||||
});
|
||||
}
|
||||
|
||||
pub struct WrapperData {
|
||||
// Our relative position within the cell
|
||||
pub(crate) cell_x_block_position: usize,
|
||||
@@ -136,18 +167,14 @@ impl DensityInterpolator {
|
||||
// These are all dummy values to be populated when sampling values
|
||||
Self {
|
||||
input_index,
|
||||
start_buffer: vec![
|
||||
0.0;
|
||||
start_buffer: get_buffer(
|
||||
(builder_options.vertical_cell_count + 1)
|
||||
* (builder_options.horizontal_cell_count + 1)
|
||||
]
|
||||
.into_boxed_slice(),
|
||||
end_buffer: vec![
|
||||
0.0;
|
||||
* (builder_options.horizontal_cell_count + 1),
|
||||
),
|
||||
end_buffer: get_buffer(
|
||||
(builder_options.vertical_cell_count + 1)
|
||||
* (builder_options.horizontal_cell_count + 1)
|
||||
]
|
||||
.into_boxed_slice(),
|
||||
* (builder_options.horizontal_cell_count + 1),
|
||||
),
|
||||
first_pass: Default::default(),
|
||||
second_pass: Default::default(),
|
||||
third_pass: Default::default(),
|
||||
@@ -214,6 +241,19 @@ impl DensityInterpolator {
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for DensityInterpolator {
|
||||
fn drop(&mut self) {
|
||||
recycle_buffer(std::mem::replace(
|
||||
&mut self.start_buffer,
|
||||
Vec::new().into_boxed_slice(),
|
||||
));
|
||||
recycle_buffer(std::mem::replace(
|
||||
&mut self.end_buffer,
|
||||
Vec::new().into_boxed_slice(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
impl MutableChunkNoiseFunctionComponentImpl for DensityInterpolator {
|
||||
fn sample(
|
||||
&mut self,
|
||||
@@ -336,6 +376,15 @@ impl MutableChunkNoiseFunctionComponentImpl for FlatCache {
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for FlatCache {
|
||||
fn drop(&mut self) {
|
||||
recycle_buffer(std::mem::replace(
|
||||
&mut self.cache,
|
||||
Vec::new().into_boxed_slice(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
impl FlatCache {
|
||||
pub fn new(
|
||||
input_index: usize,
|
||||
@@ -347,8 +396,7 @@ impl FlatCache {
|
||||
) -> Self {
|
||||
Self {
|
||||
input_index,
|
||||
cache: vec![0.0; (horizontal_biome_end + 1) * (horizontal_biome_end + 1)]
|
||||
.into_boxed_slice(),
|
||||
cache: get_buffer((horizontal_biome_end + 1) * (horizontal_biome_end + 1)),
|
||||
start_biome_x,
|
||||
start_biome_z,
|
||||
horizontal_biome_end,
|
||||
@@ -589,13 +637,11 @@ impl CellCache {
|
||||
) -> Self {
|
||||
Self {
|
||||
input_index,
|
||||
cache: vec![
|
||||
0.0;
|
||||
cache: get_buffer(
|
||||
build_options.horizontal_cell_block_count
|
||||
* build_options.horizontal_cell_block_count
|
||||
* build_options.vertical_cell_block_count
|
||||
]
|
||||
.into_boxed_slice(),
|
||||
* build_options.vertical_cell_block_count,
|
||||
),
|
||||
min_value,
|
||||
max_value,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user