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
44 changes: 32 additions & 12 deletions examples/stress_tests/many_components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,14 @@ use bevy::{

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

// 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,40 @@ 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| {
let values: Vec<OwningPtr> = components
.iter()
.map(|_id| {
let mut value: u8 = rng.gen_range(0..255);
let value = &mut value;
// SAFETY: value is non null since it was initialized from an &mut above
#[allow(unsafe_code)]
let ptr = unsafe { NonNull::new_unchecked(value as *mut u8) };
#[allow(unsafe_code)]
// SAFETY:
// component_id is from the same world
// value is u8, so ptr is a valid reference for component_id
unsafe {
entity.insert_by_id(component_id, ptr);
OwningPtr::new(ptr)
hymm marked this conversation as resolved.
Show resolved Hide resolved
}
});
})
.collect();
// SAFETY:
// * component_id is from the same world
// * values was initialized above, so references are valid
#[allow(unsafe_code)]
unsafe {
entity.insert_by_ids(&components, values.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