-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Closed
Labels
A-RenderingDrawing game state to the screenDrawing game state to the screenC-BugAn unexpected or incorrect behaviorAn unexpected or incorrect behaviorC-PerformanceA change motivated by improving speed, memory usage or compile timesA change motivated by improving speed, memory usage or compile timesP-HighThis is particularly urgent, and deserves immediate attentionThis is particularly urgent, and deserves immediate attention
Description
Bevy version
Main branch commit: d8974e7c3d84189313268f475ceeff9393cedffa
Operating system & version
Windows 10 Vulkan and DX12 API.
What you did
The example code is small and easy to understand:
use bevy::{prelude::*, diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}};
#[derive(Component)]
pub struct Nothing;
#[derive(Bundle)]
pub struct NoBundle {
nothing: Nothing,
}
fn startup(
mut commands: Commands,
) {
let mut entities = Vec::new();
for _ in 0..5000000 {
entities.push(NoBundle {
nothing: Nothing,
});
}
commands.spawn_batch(entities);
}
fn main() {
App::new()
.insert_resource(WindowDescriptor {
width: 1270.0,
height: 720.0,
title: String::from("Bug"),
..Default::default()
})
.insert_resource(ClearColor(Color::rgb(0.211, 0.643, 0.949)))
.add_plugin(FrameTimeDiagnosticsPlugin::default())
.add_plugin(LogDiagnosticsPlugin::default())
.add_plugins(DefaultPlugins)
.add_startup_system(startup)
.run();
}
What you expected to happen
Creating large amounts of entities shouldn't decrease rendering performance unless they are actually drawing something to the screen.
What actually happened
Performance decreases rapidly with increased entity counts. On higher end machines this is less noticeable, but still becomes an issue.
Additional information
The decrease in performance can be traced to this:
bevy/crates/bevy_render/src/lib.rs
Lines 193 to 202 in 458cb7a
let meta_len = app_world.entities().meta.len(); | |
render_app | |
.world | |
.entities() | |
.reserve_entities(meta_len as u32); | |
// flushing as "invalid" ensures that app world entities aren't added as "empty archetype" entities by default | |
// these entities cannot be accessed without spawning directly onto them | |
// this _only_ works as expected because clear_entities() is called at the end of every frame. | |
render_app.world.entities_mut().flush_as_invalid(); |
Reserving entity ID's for every entity seems to be costly when dealing with a large number of entities.
Possible solutions:
- Don't reserve entities that don't render anything. I'm not sure how performant that will be overall?
- Possibly this could be mitigated by using a sub world where you could store extremely large numbers of entities without the rendering world being aware of said entities.
CptPotato, gilescope and Epinomis
Metadata
Metadata
Assignees
Labels
A-RenderingDrawing game state to the screenDrawing game state to the screenC-BugAn unexpected or incorrect behaviorAn unexpected or incorrect behaviorC-PerformanceA change motivated by improving speed, memory usage or compile timesA change motivated by improving speed, memory usage or compile timesP-HighThis is particularly urgent, and deserves immediate attentionThis is particularly urgent, and deserves immediate attention