Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

many_components stress test improvements #16913

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
51 changes: 38 additions & 13 deletions examples/stress_tests/many_components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,20 @@ use bevy::{
},
log::LogPlugin,
prelude::{App, In, IntoSystem, Query, Schedule, SystemParamBuilder, Update},
ptr::OwningPtr,
ptr::{OwningPtr, PtrMut},
MinimalPlugins,
};

use rand::prelude::{Rng, SeedableRng, SliceRandom};
use rand_chacha::ChaCha8Rng;
use std::{alloc::Layout, num::Wrapping};
use std::{alloc::Layout, mem::ManuallyDrop, num::Wrapping};

// A simple system that matches against several components and does some menial calculation to create
// some non-trivial load.
fn base_system(access_components: In<Vec<ComponentId>>, mut query: Query<FilteredEntityMut>) {
#[cfg(feature = "trace")]
let _span = bevy::utils::tracing::info_span!("base_system", components = ?access_components.0, count = query.iter().len()).entered();

for mut filtered_entity in &mut query {
// We calculate Faulhaber's formula mod 256 with n = value and p = exponent.
// See https://en.wikipedia.org/wiki/Faulhaber%27s_formula
Expand Down Expand Up @@ -84,8 +87,8 @@ fn stress_test(num_entities: u32, num_components: u32, num_systems: u32) {
world.register_component_with_descriptor(
#[allow(unsafe_code)]
// SAFETY:
// we don't implement a drop function
// u8 is Sync and Send
// * We don't implement a drop function
// * u8 is Sync and Send
unsafe {
ComponentDescriptor::new_with_layout(
format!("Component{}", i).to_string(),
Expand Down Expand Up @@ -124,23 +127,45 @@ fn stress_test(num_entities: u32, num_components: u32, num_systems: u32) {
// spawn a bunch of entities
for _ in 1..=num_entities {
let num_components = rng.gen_range(1..10);
let components = component_ids.choose_multiple(&mut rng, num_components);
let components: Vec<ComponentId> = component_ids
.choose_multiple(&mut rng, num_components)
.copied()
.collect();

let mut entity = world.spawn_empty();
for &component_id in components {
let value: u8 = rng.gen_range(0..255);
OwningPtr::make(value, |ptr| {
#[allow(unsafe_code)]
// We use `ManuallyDrop` here as we need to avoid dropping the u8's when `values` is dropped
// since ownership of the values is passed to the world in `insert_by_ids`.
// But we do want to deallocate the memory when values is dropped.
let mut values: Vec<ManuallyDrop<u8>> = components
.iter()
.map(|_id| ManuallyDrop::new(rng.gen_range(0..255)))
.collect();
let ptrs: Vec<OwningPtr> = values
.iter_mut()
.map(|value| {
// SAFETY:
// component_id is from the same world
// value is u8, so ptr is a valid reference for component_id
// * We don't read/write `values` binding after this and values are `ManuallyDrop`,
// so we have the right to drop/move the values
#[allow(unsafe_code)]
unsafe {
entity.insert_by_id(component_id, ptr);
PtrMut::from(value).promote()
}
});
})
.collect();
// SAFETY:
// * component_id's are from the same world
// * `values` was initialized above, so references are valid
#[allow(unsafe_code)]
unsafe {
entity.insert_by_ids(&components, ptrs.into_iter());
}
}

println!(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be info! so it can be configured with the logging framework?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure. I see some examples use info and some use println. This example was using println already, so I just kept it consistent.

"Number of Archetype-Components: {}",
world.archetypes().archetype_components_len()
);

// overwrite Update schedule in the app
app.add_schedule(schedule);
app.add_plugins(MinimalPlugins)
Expand Down
Loading